Однострочные программы на Perl

    Введение


    Я собираюсь рассказать об однострочных программах на Perl. Если вы овладете однострочным Perl`ом, то можете сэкономить кучу времени (я экономлю).

    Цель поста — показать как Perl можно использовать заместо find, grep, awk, sed. В конце поста будет написано зачем это надо.

    Ну обо всём по порядку.

    Флаги


    Флаг -e
    Флаг позволяет запускать перловый код прямо в консоли, эту возможность я использую для проверки какого-нибудь тестового кода.
    Допустим, я хочу узнать десятичное значение шестнадцатеричного числа 0xFA23B:
    perl -e "print 0xFA23B"

    Примечание. Когда однострочный перловый код запускаем из под Винды, то код нужно заключать в двойные кавычки:
    perl -e "print 0xFA23B"
    , в случае Линукса/Юникса код может быть как в двойных кавычках, так и в одинарных, но в Юниксе/Линуксе случае двойных кавычек приходится экранировать знаки "$":
    perl -e "\$i = 0;print \$i"

    Примечание. После флага -e должен следовать сразу код.

    Флаг -l
    Это флаг делает инициализирует переменные $/ и $\ значением "\n";
    Переменная $/ задаёт разделитель входных полей.
    Переменная $\ задаёт, что будет выводиться после команды print.

    Программа:
    perl -le "print 1"

    Эквивалентна следующей:
    BEGIN { $/ = "\n"; $\ = "\n"; }
    print 1;

    Таким образом в конце не приходится писать print "\n";

    Флаг -n
    Отсюда начинается самое интересное.

    Следующий код:
    perl -ne 'print 1'

    эквивалентен этому:
    LINE: while (defined($_ = <ARGV>)) {
       print 1;
    }
    

    Где же это можно использовать?
    А вот, например, нам надо добавить к именам файлов, имена которых начинаются с цифр, расширение «bak»:

    Вуаля:
    ls | perl -lne 'rename $_, "$_.bak" if /^\d+/'

    А для Windows? Пожалуйста:
    dir /b | perl 	-lne "rename $_, \"$_.bak\" if /^\d+/"

    Посмотрим на получившуюся программу:
    BEGIN { $/ = "\n"; $\ = "\n"; }
    LINE: while (defined($_ = <ARGV>)) {
        chomp $_;
        rename $_, "$_.bak" if /^\d+/;
    }
    

    chomp $_; взялся от флага -l: он совместно с -n даёт добавляет ещё и chomp $_;, а не только BEGIN { $/ = "\n"; $\ = "\n"; }

    Флаг -a
    Флаг -a позволяет использовать Perl как awk.

    Cледующий код:
    perl -nae "print 1"

    эквивалентен:
    LINE: while (defined($_ = <ARGV>)) {
        our(@F) = split(" ", $_, 0);
        print 1;
    }
    

    То есть каждая строка расщепляется split`ом по пробелам, и получившиеся поля кладутся в массив @F.
    Разделитель полей можно поменять с помощью флага -F.

    Допустим, надо вывести из файла /etc/passwd имена пользователей с их домашними директориями:
    less /etc/passwd | perl -F: -nlae 'print "$F[0]:$F[4]"'

    А Винде я, например, хочу узнать имена файлов в папке, которые последний раз изменял в сентябре 2009:
    dir /TW | perl -nale "print $F[$#F] if $F[0] =~ /\.09\.2009/"

    Флаг -p
    Этот флаг делает тоже, что -n только добавляет ещё блок continue c «print $_».

    Следующий код:
    perl -pe "print 1"

    эквивалентен:
    LINE: while (defined($_ = <ARGV>)) {
        print 1;
    }
    continue {
        print $_;
    }
    

    Допустим, мы выводим файл /etc/passwd, попутно заменяя 3 на 6.

    Вместо такого кода:
    less /etc/passwd | perl -ne "s/3/6/;print \$_"

    Мы можем написать:
    less /etc/passwd | perl -pe "s/3/6/"

    Флаг -i
    Флаг i позволяет изменять файлы.

    Следующая программа:
    perl -i.bak -pe "s/foo/bar/"

    эквивалентна этой:
    BEGIN { $^I = ".bak"; }
    LINE: while (defined($_ = <ARGV>)) {
        s/foo/bar/;
    }
    continue {
        print $_;
    }
    

    которая в свою очередь эквивалентна этой:
    $extension = '.bak';
    LINE: while (<>) {
    if ($ARGV ne $oldargv) {
    	if ($extension !~ /\*/) {
    		$backup = $ARGV . $extension;
    	}
    	else {
    		($backup = $extension) =~ s/\*/$ARGV/g;
    	}
    	rename($ARGV, $backup);
    	open(ARGVOUT, ">$ARGV");
    	select(ARGVOUT);
    	$oldargv = $ARGV;
    	}
    	s/foo/bar/;
    }
    continue {
    	print;  # this prints to original filename
    }
    select(STDOUT);
    

    В кратце поясню, что происходит, когда вызываются строки perl -i.bak -pe «код» <имя файла>. Например, мы вызываем:
    perl -i.bak -pe "s/foo/bar/" test.txt

    Файл test.txt переименовывается в файл test.txt.bak, и создаётся новый файл test.txt. Потом в каждой строке исходного файла заменяется foo на bar, которые записываются в новый фалй test.txt (по-видимому, хоть файл и переименовали, мы всё равно имеем доступ к его строкам?)

    Допустим, нужно в файле заменить \r\n на \n:
    perl -i.bak -pe 's/\r\n/\n/' test.txt

    В результате этого кода получатся два файла: один — test.txt.bak, который является копией исходного, другой — test.txt, где \r\n заменено на \n.

    Примечание. Если вы посмотрите внимательно на программу выше ( $extension = '.bak'; ...), то увидите, что если вызывать вот так: perl -ibak_*…, то бэкапный файл будет называться «bak_test.txt», то есть если есть звёздочка в значении параметра i, то это это значение расматривается не как расширение, а как шаблон, где звёздочка обозначает имя файла.

    Флаг -M

    Флаг -M позволяет подключать модули

    Например, я хочу узнать где лежит модуль CGI:

    для Windows:
    perl -MCGI -le "print $INC{'CGI.pm'}"

    для Linux:
    perl -MCGI -le "print \$INC{'CGI.pm'}"

    Недавно мне понадобилось сделать chmod a+x всем файлам с расширением ".cgi",
    но на сервере флаг -R для chmod почему-то не работал, так вот что я сделал, что-то подобное:
    perl -MFile::Find -e 'finddepth(sub {print $File::Find::name . "\n"}, "."})' | grep -P '\.cgi$' | perl -nle '`chmod a+x $_`'

    Этим кодом «perl -MFile::Find -e 'finddepth(sub {print $File::Find::name. „\n“}, »."})'" Я вызвал функцию finddepth модуля File::Find, которая рекурсивно обошла текущую директорию и вывела полные пути файлов.

    Потом грепом я взял только те файлы, которые оканчиваются на '.cgi' (-P означает, что используются перловые регулярные выражения), а следующей программой «perl -nle '`chmod a+x $_`'» я сделал права на выполнение найденым файлам.

    Хотя этот код я мог бы записать так:
    perl -MFile::Find -e 'finddepth(sub {$n = $File::Find::name;`chmod a+x $n` if $n =~ /\.cgi$/}, ".")'

    Заметьте, что надо использовать флаг -l, чтобы в $_, попало имя файла без "\n"

    А что если надо подключить некоторые переменные или подпрограммы из подключаемого пакета в пакет main?
    Тогда надо писать:
    perl -MModule=foo,bar -e '...';

    или
    perl '-Mmodule qw(foo bar)' -e '...';

    BEGIN и END


    Можно использовать BEGIN и END, для действий, которые должны происходить в начале и в конце, аналогично как у awk.
    perl -e 'BEGIN{<начальные действия>};<действие>;END{конечные действия}';

    Например выведем линии, состоящие из 40 знаков "=" в начале и конце отчёта:
    dir /b | perl -pe "sub line {print '=' x 40 . \"\n\"};BEGIN{line();};END{line()}"

    Дебаг


    Чтобы дебажить однострочные программы надо подключать модуль B::Deparse,

    Если вы запустите:
    perl -MO=Deparse -ne "print 1"

    То получите вывод:
    LINE: while (defined($_ = <ARGV>)) {
        print 1;
    }
    -e syntax OK
    

    модуль B::Deparse нужно подключать так: "-MO=Deparse", а не так: "-MB::Deparse". Видимо это сделано для того, чтобы чётко определить, что мы хотим использовать этот модуль для вывода исходного кода программы, а не просто для использования каких его либо методов в программе.

    Вот так модуль B::Deparse будет использоваться как обычный модуль, вывода кода не будет:
    perl -MB::Deparse  -e "print 1"

    В примерах выше я использовал MO=Deparse для вывода кода программ.

    Примеры однострочных программ


    Вывод количества строк в файле (аналог Юниксовского wc -l)
    perl -ne '}{ print $.' abc.txt

    Эквивалентная программа:
    LINE: while (defined($_ = <ARGV>)) {
        ();
    }
    {
        print $.;
    }
    

    Здесь использован хитрый приём "}{". Мы сами закрыли цикл.

    Вывод двоичного числа
    perl -e "printf '%b', shift" 200

    Замена \r\n на \n в файле
    perl -i.bak -pe 's/\r\n/\n/' file.txt

    Примечание. Почему-то подобный код не работает в Винде: она упорно добавляет \r\n, я делал binmode ARGV,
    binmode $ARGV, binmode *ARG{FILEHANDLE}, но ничего не помогало, буду биться дальше. Буду благодарен вам, если напишите как заменить \r\n на \n в Винде.

    Преобразование IP адреса из формы «цифры-точки» в число:
    perl -e "print unpack('N', pack('C4', split /\./, shift))" 127.0.0.1

    Удаление папок .svn в текущей папке и её подпапках (рекурсивно)
    perl -MFile::Find -MCwd -e '$path = getcwd;finddepth(sub {print $File::Find::name."\n"}, "$path")' | grep '\.svn$' | perl -ne 'system("rm -rf $_")';

    тоже самое для Windows:
    perl -MFile::Find -e "finddepth(sub{ print $File::Find::name . \"\n\"; }, '.')" | perl -ne "print if /.svn$/" | perl -pe "s|/|\\|g" | perl -ne "system(\"rd /s /q $_\");"

    Вывод IP-aдреса в шестнадцатеричной форме
    perl -e "printf '%02x' x 4, split /\./, shift" 127.0.0.1

    Добавление строки "#!/usr/bin/perl" в начало файла
    perl -i.bak -pe "print \"#!/usr/bin/perl\n\" if $. == 1" abc.pl 

    Для Линукса/Юникса:
    perl -i.bak -pe 'print "#!/usr/bin/perl\n" if $. == 1' abc.pl

    Зачем это надо?


    Как и обещал напишу, зачем это всё надо. Вы можете сказать, что есть find, awk, grep, sed, зачем однострочный Perl?

    Ну во-первых, в Винде, по-умолчанию, грепа и awk нету. Да конечно быстрее пользоваться grep для отбора строк, но что если надо сделать чуть по-больше, например переименовать файл? Вы скажете есть ведь find, да есть. Так что же я скажу в защиту однострочного перла?

    А вот что:

    Во-первых, если программируешь на Perl, то Perl помнишь очень хорошо и можешь сразу начать писать однострочную программу, не заглядывая в man. (Поначалу, правда, может быть немного не привычно, но когда втянешься, будет легко)

    Во-вторых, бывает удобно использовать именно Perl. Например, когда я хочу иметь аналог awk (смотри флаг -a) с мощью Perl (например хочу использовать в однострочной программе функции pack, unpack или регулярные выражение Perl)

    В-третьих,
    Perl — мощный язык. Однострочная программа на perl — это обычная программа на Perl, только в командной строке. А значит однострочные программы на перл можно использовать для самых разных задач! (Но думаю, длинные однострочные программы, наверно, лучше не писать, лучше сделать обычный перловый скрипт).

    Заключение


    Не подумайте только, что я призываю отказаться от grep, find, sed или awk. Не призываю! Я сам продолжаю использовать grep, find. Просто я хотел рассказать о ещё одном полезном инструменте как «однострочный перл», который удобен для тех кто программирует на Perl, ибо: 1) не надо читать man (ты и так всё помнишь), 2) используется мощь Perl

    Спасибо за внимание. Тех кто заинтересовался отсылаю сюда:

    perldoc.perl.org/perlrun.html — perldoc, описание всех флагов.
    sial.org/howto/perl/one-liner — разные примеры

    Советую гуглить перловые однострочные программы с словом: one-liners

    обн:
    Чтобы заменить \r\n на \n в Винде, надо просто написать:
    perl -i.bak -ple "s/\r|\n//g;binmode ARGVOUT" file.txt

    Респект AntonShcherbinin

    обн:
    Добавил в код от AntonShcherbinin, "s/\r|\n//g;", а то в Линуксе просто binmode не прокатывает, теперь этот код универсален: работает и в Винде, и в Линуксе.

    обн (26.08.2012):
    Переписал примеры кода под теги <source lang=«Perl»></source>
    Поделиться публикацией

    Похожие публикации

    Комментарии 45
      0
      Перенесите сюда habrahabr.ru/blogs/perl/
        0
        Не могу, кармы нема. Я тут новенький
        +2
        А как же тот самый? :)
        >perl -e '$??s:;s:s;;$?::s;;=]=>%-{
          0
          парсер — лох, схавал больше половины однострочника :/
            +4
            вот он — тот самый:

            cat «test… test… test...» | perl -e '$??s:;s:s;;$?::s;;=]=>%-{<-|}<&|`{;;y; -/:-@[-`{-};`-{/" -;;s;;$_;see'



            тем, кто будет запускать, советую сначала прочесть это siv.habrahabr.ru/blog/70649/
              +6
              Старый патч…
              Помнится его часто на убунте применяли те, у кого иксы падали.
              +4
              парсер догадывается о назначении =)
              +4
              ну и конечно, это должен прочесть каждый — www.linux.org.ru/view-message.jsp?msgid=392747&page=-1

              :)
              0
              хорошо, что вы написали про «зачем то надо?» — а то я уже стал писать про rename+find+awk… ))

              статья очень хорошая, респект.

                +2
                вот за что я люблю могучий Perl…
                в избранное, спасибо :)
                  +3
                  perl заслуженно входит в клуб write-only языков
                    +4
                    Смотря как писать.
                    +1
                    LINE: while (defined($_ = )) {
                    print 1;
                    }

                    У вас тут Хабр съел <> — исправьте :)
                      0
                      Благодарю, исправил.
                      0
                      Задумался! :-) Я использовал -e только для проверки наличия модуля :-)
                        0
                        Всегда таскаю с собой утилитку для проверки наличия модулей и их версий:
                        #!/usr/bin/env perl
                        
                        my $module = shift;
                        
                        my $is_loaded = eval "require $module; $module->import; 1";
                        unless($is_loaded) {
                            print "$module was not loaded: $@"
                        }
                        else {
                            print $module->VERSION || 'Loaded, but no $VERSION defined'
                        }
                        print $/
                        

                        Называю её mver. Удобней, чем набирать каждый раз perl -MModule -e1
                          0
                          Сделал утилитку для поиска файлов регулярным выражением (для Никсов говорят find поддерживает регулярки)

                          rs.bat (rs — regexp search)
                          perl -MFile::Find -MCwd -le "$path = getcwd;finddepth(sub {print $File::Find::name if %1}, $path)"

                          Прописал в системные переменные путь к ней.

                          теперь вызываю её так:
                          rs /<регулярное выражение>/<флаги>

                          пример: rs /\.pl$/
                        0
                        Буду благодарен вам, если напишите как заменить \r\n на \n в Винде.
                        Если мне требуется гарантированно разграничить \r\n и \n, я предпочитаю писать явным образом \x0d и \x0a вместо \r и \n.
                          +2
                          Еще стоит отметить, что в 5.10 появился отличный ключик -E, который включает директиву features:

                          perl -E'say "hello"'
                          

                          Теперь даже -l не нужен.
                            0
                            Я бы добавил ещё небольшое пояснение по поводу ключа -p, касательно его применения.
                            При использовании «скрипта» после | в «скрипт» (при -p) весь вывод предыдущей утилиты попадает разом (в STDIN), в то время, как без -p к каждой строке будет применён «скрипт» индивидуально (где «ввод» будет в $_) :)
                            Т.е. когда надо заменить переносы строк на табуляции, например, то используем
                            cat config.xml | perl -pe 'do{s/\n/\t/;print}while <>'
                              0
                              Я сделал тестовый пример:

                              Файл abc.txt такого содержания.
                              #!/usr/bin/perl
                              #!/usr/bin/perl
                              Xывафfdasdfasfd
                              asdfasfda
                              sfasdfasfd
                              asfdasdfa
                              sdfasdfasfd


                              потом запустил
                              type abc.txt | perl -pe "print $_;last"

                              Мне вывело только "#!/usr/bin/perl". Так что Вы уверены, насчёт Вашего высказывания?
                                0
                                Т.е. когда надо заменить переносы строк на табуляции, например, то используем
                                cat config.xml | perl -pe 'do{s/\n/\t/;print}while <>'

                                Вы, видимо, не понимаете самой сути ключа -p. -p означает «print». Т. е. этот ключ избавляет вас от необходимости печатать строку после того, как вы её изменили, т. к. печать будет сделана автоматически. Кроме того, это дополнение к -n, т. е. помимо вывода строки этот ключ организует цикл по всем строкам входного файла, а ваш «скрипт» является лишь телом этого цикла. Т. е. при использовании -p в 99.9% случаев никаких while <> в явном виде писать не надо.

                                В итоге, чтобы решить вашу задачу (заменить \n на \t в файле config.xml ) с помощью Perl, нужно сказать

                                perl -wpe 'tr/\n/\t/' config.xml

                                И никаких while, никаких print: их Perl делает за вас.
                                Да, я чуть не забыл сказать, что писать
                                cat file |
                                тоже не нужно (и это плохая привычка). Perl (и любая правильная POSIX-утилита) замечательно умеет читать файл сам, помощник в виде cat ему не нужен. Поэтому просто укажите имя файла в виде последнего аргумента перлу, и «усё, шеф!» :)
                                +11
                                Советую ознакомится с однострочниками Бена Окопника, написанными в детективном стиле:

                                gazette.linux.ru.net/lg84/okopnik.html
                                gazette.linux.ru.net/lg85/okopnik.html
                                gazette.linux.ru.net/lg86/okopnik.html
                                gazette.linux.ru.net/lg87/okopnik.html
                                gazette.linux.ru.net/lg88/okopnik.html
                                gazette.linux.ru.net/lg89/okopnik.html
                                  0
                                  Спасибо=))
                                  Никогда не читал, клевая штука!
                                  +2
                                  Все супер, спасибо автору, но это удивило

                                  «Недавно мне понадобилось сделать chmod a+x всем файлам с расширением ».cgi",
                                  но на сервере флаг -R для chmod почему-то не работал, так вот что я сделал, что-то подобное:

                                  perl -MFile::Find -e 'finddepth(sub {print $File::Find::name. "\n"}, "."})' | grep -P '\.cgi$' | perl -nle '`chmod a+x $_`'"

                                  Можно же было find. -name *.cgi | perl -nle '`chmod a+x $_`'"

                                  Я прекрасно понимаю, что идея топика — показать мощь однострочек перла, но не удержался, извините :)
                                    +3
                                    find. -name '*.cgi' -type f -exec chmod a+x '{}' \;
                                      0
                                      :-), просто я с find пока не очень дружу. Благодарю.
                                        +2
                                        В данном случае применение File::Find, далеко не самого очевидного модуля, скорее оттолкнёт людей от Perl, чем приблизит к нему. Ваш вариант лучше, чем у автора статьи, но всё равно значительно менее нагляден и эффективен, чем естественное

                                        find . -name \*.cgi | xargs chmod +x

                                        (если есть шанс «напороться» на файлы с пробелами в имени, нужно добавить -print0 для find и -0 для xargs). Если, скажем, на диске окажется 150 .cgi-файлов, то ваш вариант запустит 150 процессов chmod, а последний вариант — только 1.

                                        Кроме того, раз уж вы используете Perl, то почему бы не использовать перловую функцию chmod() ?
                                          0
                                          перловый chmod поддерживает только цифры.
                                            +1
                                            Совершенно верно, как и сишная функция chmod(), которую Perl вызывает. Поэтому, чтобы изменить текущие разрешения файла, нужно сначала их получить. Это удлиняет программу букв этак на 20, но это Perl way. Вот это ваш вариант:
                                            perl -MFile::Find -e 'finddepth(sub {$n = $File::Find::name;`chmod a+x $n` if $n =~ /\.cgi$/}, ".")'
                                            А вот вариант на Perl:

                                            perl -MFile::Find -we 'find(sub {/\.cgi$/ and chmod((stat)[2] || 0111)}, ".")'
                                          0
                                          можно было и еще проще :) через -exec
                                            0
                                            Да это понятно. Но я тут хотел показать применение перла вместе с шеллом :)
                                              0
                                              Да, я уже понял :) Все равно интересно, ибо демонстрирует альтернативные методы решения задач. Потому что действительно, для тривиальных нужд чистый шелл может и удобнее, но с ростом сложности условия, сложность скрипта растет быстрее :) Тогда уже перл начинает рулить.
                                          +3
                                          perl -i.bak -pe 's/\r\n/\n/' file.txt

                                          Примечание. Почему-то подобный код не работает в Винде: она упорно добавляет \r\n, я делал binmode ARGV,
                                          binmode $ARGV, binmode *ARG{FILEHANDLE}, но ничего не помогало, буду биться дальше. Буду благодарен вам, если напишите как заменить \r\n на \n в Винде.

                                          «Когда вы совсем отчаялись, перепробовали все варианты, но ничего не помогает, прочтите, наконец, инструкцию» ;-)

                                          perl -i.bak -pe «binmode ARGVOUT» file.txt

                                          (Хабр заменил прямые кавычки на кавычки «ёлочкой», не знаю, как его отучить)
                                          Ещё раз подчеркну, что это код для Windows. Никакие замены \r\n на \n в явном виде не нужны, потому что именно это делает сама Windows, читая из файла file.txt. Нужно лишь попросить Windows не делать обратного преобразования при записи в выходной файл, сказав binmode ARGVOUT.
                                          Ирония состоит в том, что вы сами, OlegTar, послали всех читать perldoc perlrun (искать ARGVOUT), где и содержится ответ :o)
                                            0
                                            +1, Благодарю.
                                            0
                                            Примечание. Флаг -e должен стоять последним среди всех флагов.


                                            perl -e «print 'That';» -e «print 'is not';» -e «print 'true'» -wl

                                            Флаг -e может стоять каким угодно среди всех флагов, но если вы неправильно пользуетесь объединением ключей и, имея в виду

                                            perl -e 'print 1' -w -l

                                            , пишете

                                            perl -ewl '-print 1'

                                            То у вас, действительно, ничего не получится, т. к. wl будут интерпретированы как текст перловой программы, которую нужно выполнить, а не как ключи для самого perl. Но это не значит, что -e должен быть последним. Пишите perl -e 'program' -f -o -o, и всё будет в ажуре.
                                              0
                                              Поправил
                                              +1
                                              Удаление папок .svn в текущей папке и её подпапках (рекурсивно)

                                              perl -MFile::Find -MCwd -e '$path = getcwd;finddepth(sub {print $File::Find::name."\n"}, "$path")' | grep '\.svn$' | perl -ne 'system(«rm -rf $_»)';

                                              тоже самое для Windows:

                                              perl -MFile::Find -e «finddepth(sub{ print $File::Find::name. \»\n\"; }, '.')" | perl -ne «print if /.svn$/» | perl -pe «s|/|\\|g» | perl -ne «system(\»rd /s /q $_\");"


                                              Раз уж вы ратуете за Perl way, то стОит использовать Perl «на полную катушку», а не как замену find (в случае Unix) или несколько perl как замену find, grep, sed и запускалку rd (в случае Windows):

                                              perl -MFile::Find -we 'finddepth(sub {$File::Find::name =~ m"/\.svn(/|$)" and -f()? unlink(): rmdir()}, ".")'

                                              Это будет работать и в Unix, и в Windows (хотя в Windows, конечно, нужно поменять двойные кавычки на апострофы, и наоборот). И никакие костыли в виде grep, find и rm/rmdir перлу не нужны.
                                                0
                                                Благодарю.
                                                А зачем всё решать именно перлом?
                                                  0
                                                  А ссори, перл — это кроссплатформенно.
                                                  0
                                                  Ничего, что rmdir перловый удаляет только пустые директории?

                                                  Из перлдок
                                                  «Deletes the directory specified by FILENAME if that directory is empty»
                                                  0
                                                  а работают в операторе s/// переменные $1 и тп?
                                                  c ключами -pe не работают, в perlrun чота не нашел
                                                    +1
                                                    Работают.
                                                    Если Вы делаете под Линукс, то либо используйте одинарные кавычки для кода, либо двойные, но тогда придётся экранировать доллары:

                                                    perl -pe 's/(.*)/bla-bla-$1/'

                                                    или

                                                    perl -pe "s/(.*)/bla-bla-\$1/"
                                                      0
                                                      ага, спасибо, не сообразил сначала, что bash тоже интерпретирует переменные =)
                                                    0
                                                    Работают.
                                                    Если Вы делаете под Линукс, то либо используйте одинарные кавычки для кода, либо двойные, но тогда придётся экранировать доллары:

                                                    perl -pe 's/(.*)/bla-bla-$1/'

                                                    или

                                                    perl -pe "s/(.*)/bla-bla-\$1/"

                                                    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                                    Самое читаемое