Несмотря на то, что я вот уже несколько месяцев не пишу на Perl по-настоящему (после того, как сменил работу), я продолжаю использовать этот язык для создания небольших скриптов и однострочников. Если вы часто работаете с *nix, Perl может здорово облегчить вам жизнь. Каким образом — будет показано в этой заметке.
Затянувшееся введение про синтаксис и CPAN
Я предполагаю, что вы более-менее знакомы с синтаксисом Perl. Если это не так, обратите внимание на соответствующую серию уроков , опубликованную в свое время в этом блоге.
Ниже я буду использовать некоторые CPAN-модули. Если вы не знаете или вдруг подзабыли, устанавливаются эти модули с помощью утилиты cpan. Например, чтобы установить модуль URI::Escape в Debian или Ubuntu, нужно выполнить команду:
Также существует более удобная утилита cpanm. Используется она точно так же, как cpan, только без флага -i. Если у вас в системе нет cpanm, просто поставьте модуль App::cpanminus.
Некоторые модули не удастся установить описанным выше образом. Обычно это бывает, когда часть модуля написана на Си. Как правило, в таких случаях модуль доступен в виде бинарного пакета для вашей системы.
Если вы не знаете имя нужного вам модуля, воспользуйтесь сайтом metacpan.org . Например, если вы ищите модуль для работы с JSON, просто введите в строке поиска «json». В ответ вы получите большой список модулей. При клике на имени модуля вы увидите исчерпывающую документацию по нему. В именах некоторых модулей могут использоваться сокращения «PP» или «XS». Первое означает, что модуль написан на чистом Perl ( p ure p erl) и прекрасно переносим между различными операционными системами. Во втором случае модуль написан на Си. Такие модули очень быстры, но плохо переносимы.
Основные сведения об однострочниках на Perl
Хорошо, теперь перейдем к однострочникам. Однострочник — это небольшая (в одну строку) команда, которая пишется прямо в оболочке и часто объединяет утилиты cut, grep и другие с помощью пайпов. Типичный однострочник выглядит как-то так:
Здесь мы читаем csv-файл, удаляем из прочитанного все столбцы, кроме второго, а затем из всех строк оставляем только те, что не содержат подстроку «afiskon». Однострочники очень удобны при решении не самых тривиальных мелких задач, но их возможности сильно ограничены. Если только вы не владеете Perl!
Интерпретатор Perl имеет флаг -e , который означает «интерпретировать строку, переданную интерпретатору в качестве аргумента, как программу на Perl». Вот простейший однострочник на Perl, преобразующий число из десятичной системы счисления в шестнадцатеричную:
Также предусмотрен флаг -l , предназначенный для автоматического добавления символа новой строки к выводимым строкам. Другими словами, «обратный» однострочник, преобразующий число из шестнадцатеричной системы в десятичную, можно написать так:
Рассмотрим чуть более сложный пример:
Здесь мы смотрим содержимое каталога cgi-bin и выводим все найденные в нем файлы (то есть, не каталоги и тп). Тут как нельзя кстати оказываются такие особенности Perl, как переменная $_ и функции, работающие с ней, возможность не писать точку с запятой в конце выражения, и другие.
Рассмотрим еще один пример. Обычно для поиска файлов я использую find или grep с ключем -r, но иногда их возможностей недостаточно. Например, как-то раз мне понадобилось найти все текстовые файлы, содержащие строку «test» и не содержащих строку «debug». Обе строки — нечувствительны к регистру. Вот возможное решение:
Здесь мы воспользовались новым флагом -n . Он означает «брать каждую строку из stdin и вызывать для нее программу, передав эту строку в переменной $_». При одновременном использовании флагов -l и -n, из входных строк удаляются символы новой строки. Что же делает сама программа?
Она проверяет, является ли файл с именем, хранимом в переменной $_, текстовым (оператор -T). Если это так, содержимое файла считывается в переменную $d. Если содержимое файла удовлетворяет требуемому условию, что мы проверяем при помощи регулярных выражений , его имя выводится, иначе — не выводится.
Весьма полезен флаг -p . Он аналогичен -n за тем исключением, что после выполнения программы автоматически выводится содержимое переменной $_. Это позволяет писать вещи вроде:
… что, бесспорно, очень удобно.
Собственно обещанная подборка
Для того, чтобы подгрузить сторонний модуль, интерпретатор Perl имеет флаг -M . Например, так можно производить кодирование и декодирование в/из base64:
perl -MMIME::Base64 -le ‘print decode_base64(«cGFzc3dvcmQ=»)’
Аналогично с urlencode:
perl -MURI::Escape -le ‘print uri_unescape(«%D0%BF%D1%80%D0%B8%D0%B2»)’
Некоторые модули требует, чтобы импорт функций в текущее пространство имен происходил явно. Например, так работает Digest::MD5:
Кстати, с помощью Perl вы можете взламывать md5-хэши прямо в консоли:
Для работы с другими алгоритмами хэширования на CPAN есть модули Digest::SHA1, Digest::SHA2, Digest::CRC (или String::CRC32, который делает то же самое) и прочие Digest::*.
С помощью Perl вы можете с легкостью пропарсить JSON. Следующий однострочник находит десять последних твитов, в которых упоминается Perl:
perl -MJSON::XS -lne ‘$j=decode_json($_); print join(«n», map { $_->{text} } @{$j->{results}})’
Парсить XML в однострочниках несколько сложнее, но если перед вами встанет такая задача, посмотрите в сторону модуля XML::Parser.
Довольно часто возникает необходимость произвести какие-то действия с временем в формате unix timestamp. Получить текущее время с помощью Perl можно так:
Декодировать время в понятное человеку представление можно командой:
Чтобы получить представление заданного времени в unix timestamp, воспользуйтесь следующим однострочником:
Не менее распространена ситуация, когда некую команду нужно выполнять периодически. Вот как это можно сделать с помощью Perl:
Есть такой известный среди питонистов способ быстро расшарить заданный каталог по HTTP:
На Perl то же самое можно сделать с помощью модуля HTTP::Server::Brick:
На случай, если все приведенные ранее примеры показались вам игрушечными, я подготовил несколько реальных однострочников, которые мне приходилось писать совсем недавно.
Сделать checkout ветки dev в дюжине различных каталогов:
Дернуть большое количество урлов с заданными аргументами:
Преобразовать результат выполнения select-запроса в CSV:
И последний однострочник:
Как выконечно жепонялион проигрывает случайный mp3-файл.
Заключение
В целом