Несмотря на то, что я вот уже несколько месяцев не пишу на Perl по-настоящему (после того, как сменил работу), я продолжаю использовать этот язык для создания небольших скриптов и однострочников. Если вы часто работаете с *nix, Perl может здорово облегчить вам жизнь. Каким образом — будет показано в этой заметке.

Затянувшееся введение про синтаксис и CPAN

Я предполагаю, что вы более-менее знакомы с синтаксисом Perl. Если это не так, обратите внимание на соответствующую серию уроков , опубликованную в свое время в этом блоге.

Ниже я буду использовать некоторые CPAN-модули. Если вы не знаете или вдруг подзабыли, устанавливаются эти модули с помощью утилиты cpan. Например, чтобы установить модуль URI::Escape в Debian или Ubuntu, нужно выполнить команду:

sudo cpan -i URI::Escape

Также существует более удобная утилита cpanm. Используется она точно так же, как cpan, только без флага -i. Если у вас в системе нет cpanm, просто поставьте модуль App::cpanminus.

Некоторые модули не удастся установить описанным выше образом. Обычно это бывает, когда часть модуля написана на Си. Как правило, в таких случаях модуль доступен в виде бинарного пакета для вашей системы.

Если вы не знаете имя нужного вам модуля, воспользуйтесь сайтом metacpan.org . Например, если вы ищите модуль для работы с JSON, просто введите в строке поиска «json». В ответ вы получите большой список модулей. При клике на имени модуля вы увидите исчерпывающую документацию по нему. В именах некоторых модулей могут использоваться сокращения «PP» или «XS». Первое означает, что модуль написан на чистом Perl ( p ure p erl) и прекрасно переносим между различными операционными системами. Во втором случае модуль написан на Си. Такие модули очень быстры, но плохо переносимы.

Основные сведения об однострочниках на Perl

Хорошо, теперь перейдем к однострочникам. Однострочник — это небольшая (в одну строку) команда, которая пишется прямо в оболочке и часто объединяет утилиты cut, grep и другие с помощью пайпов. Типичный однострочник выглядит как-то так:

cat file.csv | cut -d ‘;’ -f 2 | grep -v afiskon

Здесь мы читаем csv-файл, удаляем из прочитанного все столбцы, кроме второго, а затем из всех строк оставляем только те, что не содержат подстроку «afiskon». Однострочники очень удобны при решении не самых тривиальных мелких задач, но их возможности сильно ограничены. Если только вы не владеете Perl!

Интерпретатор Perl имеет флаг -e , который означает «интерпретировать строку, переданную интерпретатору в качестве аргумента, как программу на Perl». Вот простейший однострочник на Perl, преобразующий число из десятичной системы счисления в шестнадцатеричную:

perl -e ‘printf «%xn», 1234’

Также предусмотрен флаг -l , предназначенный для автоматического добавления символа новой строки к выводимым строкам. Другими словами, «обратный» однострочник, преобразующий число из шестнадцатеричной системы в десятичную, можно написать так:

perl -le ‘print 0x4da’

Рассмотрим чуть более сложный пример:

perl -le ‘while(glob «cgi-bin/*»){ print if -f }’

Здесь мы смотрим содержимое каталога cgi-bin и выводим все найденные в нем файлы (то есть, не каталоги и тп). Тут как нельзя кстати оказываются такие особенности Perl, как переменная $_ и функции, работающие с ней, возможность не писать точку с запятой в конце выражения, и другие.

Рассмотрим еще один пример. Обычно для поиска файлов я использую find или grep с ключем -r, но иногда их возможностей недостаточно. Например, как-то раз мне понадобилось найти все текстовые файлы, содержащие строку «test» и не содержащих строку «debug». Обе строки — нечувствительны к регистру. Вот возможное решение:

find . / | perl -lne ‘if(-T $_){ $d = `cat «$_»`; print if ($d =~ /test/i) && ($d !~ /debug/i) }’

Здесь мы воспользовались новым флагом -n . Он означает «брать каждую строку из stdin и вызывать для нее программу, передав эту строку в переменной $_». При одновременном использовании флагов -l и -n, из входных строк удаляются символы новой строки. Что же делает сама программа?

Она проверяет, является ли файл с именем, хранимом в переменной $_, текстовым (оператор -T). Если это так, содержимое файла считывается в переменную $d. Если содержимое файла удовлетворяет требуемому условию, что мы проверяем при помощи регулярных выражений , его имя выводится, иначе — не выводится.

Весьма полезен флаг -p . Он аналогичен -n за тем исключением, что после выполнения программы автоматически выводится содержимое переменной $_. Это позволяет писать вещи вроде:

echo ‘hello, world!’ | perl -pe ‘s/hello/goodbye/i’

… что, бесспорно, очень удобно.

Собственно обещанная подборка

Для того, чтобы подгрузить сторонний модуль, интерпретатор Perl имеет флаг -M . Например, так можно производить кодирование и декодирование в/из base64:

perl -MMIME::Base64 -le ‘print encode_base64(«password»)’
perl -MMIME::Base64 -le ‘print decode_base64(«cGFzc3dvcmQ=»)’

Аналогично с urlencode:

perl -MURI::Escape -le ‘print uri_escape(«привет»)’
perl -MURI::Escape -le ‘print uri_unescape(«%D0%BF%D1%80%D0%B8%D0%B2»)’

Некоторые модули требует, чтобы импорт функций в текущее пространство имен происходил явно. Например, так работает Digest::MD5:

perl -MDigest:: MD5 =md5_hex -le ‘print md5_hex(«kitty»)’

Кстати, с помощью Perl вы можете взламывать md5-хэши прямо в консоли:

time perl -MDigest:: MD5 =md5_hex -le ‘for(«a»..»zzzzz») { if(md5_hex($_) eq «cd880b726e0a0dbd4237f10d15da46f4») {print; last} }’

Для работы с другими алгоритмами хэширования на CPAN есть модули Digest::SHA1, Digest::SHA2, Digest::CRC (или String::CRC32, который делает то же самое) и прочие Digest::*.

С помощью Perl вы можете с легкостью пропарсить JSON. Следующий однострочник находит десять последних твитов, в которых упоминается Perl:

wget ‘http://search.twitter.com/search.json?q=Perl’ -O |
perl -MJSON::XS -lne ‘$j=decode_json($_); print join(«n», map { $_->{text} } @{$j->{results}})’

Парсить XML в однострочниках несколько сложнее, но если перед вами встанет такая задача, посмотрите в сторону модуля XML::Parser.

Довольно часто возникает необходимость произвести какие-то действия с временем в формате unix timestamp. Получить текущее время с помощью Perl можно так:

perl -le ‘print time()’

Декодировать время в понятное человеку представление можно командой:

perl -le ‘print scalar localtime(1345006368)’

Чтобы получить представление заданного времени в unix timestamp, воспользуйтесь следующим однострочником:

perl -MDate::Manip -le ‘print UnixDate(«2012/08/05», «%s»)’

Не менее распространена ситуация, когда некую команду нужно выполнять периодически. Вот как это можно сделать с помощью Perl:

perl -e ‘while(1) { system(«cat worker.log | grep Failed | wc -l»); sleep 60 }’

Есть такой известный среди питонистов способ быстро расшарить заданный каталог по HTTP:

python -m SimpleHTTPServer

На Perl то же самое можно сделать с помощью модуля HTTP::Server::Brick:

perl -MHTTP::Server::Brick -e ‘$s = HTTP::Server::Brick->new; $s->mount(«/» => { path => «./» }); $s->start()’

На случай, если все приведенные ранее примеры показались вам игрушечными, я подготовил несколько реальных однострочников, которые мне приходилось писать совсем недавно.

Сделать checkout ветки dev в дюжине различных каталогов:

perl -le ‘for(<./deps/*>) { chdir($_); print «=== $_===»; system(«git checkout dev 2>/dev/null && git pull origin dev»); chdir(«../..»); }’

Дернуть большое количество урлов с заданными аргументами:

cat id_list.txt | perl -lne ‘chomp; system(«wget «http://example.ru/api/v1.0/items?item_id=$_»»»»)’

Преобразовать результат выполнения select-запроса в CSV:

cat / tmp / rslt.txt | perl -e ‘while(<>){ next if ++$n == 2; s/^s+//; s/s+$//; s/|s+/|/g; s/s+|/|/g; s/|/;/g; print «»$_n»»}’

И последний однострочник:

perl -e ‘@f = <*.*>; system «»mpg123 «».$f[rand(@f)]’

Как выконечно жепонялион проигрывает случайный mp3-файл.

Заключение

В целом

admin

Share
Published by
admin

Recent Posts

Apple: история логотипа

Как менялся логотип Apple на протяжении многих лет. Логотип Apple — это не просто символ,…

6 дней ago

Security Boot Fail при загрузке Acer — решение проблемы

Security Boot Fail при загрузке Acer — решение проблемы При загрузке ноутбука Acer с флешки,…

3 недели ago

Ноутбук не включается — варианты решения

Ноутбук не включается — варианты решения Если при попытке включить ноутбук вы обнаруживаете, что он…

3 недели ago

The AC power adapter wattage and type cannot be determined — причины и решение

The AC power adapter wattage and type cannot be determined — причины и решение При…

3 недели ago

Свистит или звенит блок питания компьютера — причины и решения

Свистит или звенит блок питания компьютера — причины и решения Некоторые владельцы ПК могут обратить…

3 недели ago

Мигает Caps Lock на ноутбуке HP — почему и что делать?

Мигает Caps Lock на ноутбуке HP — почему и что делать? При включении ноутбука HP…

3 недели ago