Perl часто называют языком прошлого, но в 2026 году он остаётся рабочим инструментом администратора и разработчика. В июле 2026 вышла стабильная ветка 5.44, ветка 5.42 поддерживается security-патчами, а CPAN по-прежнему огромен. Главная сила Perl — обработка текста, разбор логов, склейка разнородных систем и быстрые однострочники.
Разберём современный стиль, практические приёмы для логов и текстов, работу с модулями и тестами, а также меры, которые не дадут превратить скрипт в необслуживаемый legacy.
Где Perl уместен сегодня
- Разбор и нормализация текстовых форматов, CSV, логов, конфигов.
- Обвязка вокруг CLI-утилит и системных API.
- Быстрые однострочники вместо длинных цепочек sed и awk.
- Поддержка существующего кода: почтовые фильтры, отчёты, мониторинг.
Для новых веб-приложений чаще выбирают другие языки, но для задач обработки данных Perl компактен и предсказуем. Важно писать современно: strict, warnings, подписи функций и явная обработка ошибок.
Современный синтаксис
Начиная с 5.36 подписи стабильны, а use v5.40 задаёт современный набор возможностей. Не смешивайте старый и новый стиль в одном файле.
use v5.40;
use strict;
use warnings;
use autodie;
sub read_lines ($path) {
open my $fh, '<:encoding(UTF-8)', $path;
return <$fh>;
}
autodie превращает неудачные системные вызовы в исключения, поэтому проверки or die после каждого open больше не нужны. Для классов в 5.38+ есть use feature 'class', но в прикладных скриптах обычные пакеты и хэши всё ещё уместнее.
Однострочники для текста
Ключевые флаги: -n — цикл по строкам без вывода, -p — с выводом, -l — автообрезка перевода строки, -a — разбиение на поля @F, -i — правка файла на месте.
perl -lane 'print $F[0]' access.log
perl -ne 'print if / 5\d\d /' access.log
perl -i.bak -pe 's/\r$//' notes.txt
perl -MJSON::PP -0777 -e 'print JSON::PP->new->decode(<>)->{version}' package.json
Всегда делайте резервную копию при -i: суффикс .bak сохраняет оригинал. Для Unicode указывайте кодировку явно через -CSDA или binmode, иначе кириллица превратится в мусор.
Разбор логов с именованными захватами
Именованные группы делают регулярное выражение читаемым, а результат — самодокументированным. Пример ниже разбирает строку веб-сервера и печатает ответы с ошибками.
use v5.40;
use strict;
use warnings;
my $re = qr{
^(?<ip>\S+) \s+ \S+ \s+ \S+ \s+
\[(?<time>[^\]]+)\] \s+
"(?<method>\S+) \s+ (?<path>\S+)[^"]*" \s+
(?<status>\d{3}) \s+ (?<bytes>\d+)
}x;
while (my $line = <STDIN>) {
next unless $line =~ $re;
my %f = %+;
say "$f{status} $f{path}" if $f{status} >= 500;
}
Хэш %+ содержит только успешно совпавшие именованные группы. Такой разбор устойчивее цепочек split и легче проверяется тестами. Для больших файлов читайте построчно, а не через slurp: память останется постоянной.
JSON, HTTP и CSV без тяжёлых зависимостей
В ядре есть JSON::PP и HTTP::Tiny. Этого достаточно для служебных интеграций; для сложных схем берите JSON::XS или Cpanel::JSON::XS.
use HTTP::Tiny;
use JSON::PP qw(decode_json);
my $http = HTTP::Tiny->new(timeout => 5);
my $res = $http->get('https://api.example.com/health');
die $res->{status} unless $res->{success};
my $data = decode_json($res->{content});
Для CSV используйте Text::CSV: наивный split /,/ ломается на кавычках и переводах строк внутри полей. Установка модулей — через cpanm, а не через системный пакетный менеджер.
cpanm --local-lib="$HOME/perl5" Text::CSV
perl -I"$HOME/perl5/lib/perl5" -MText::CSV -e 'print $Text::CSV::VERSION'
perl -c script.pl
prove -l t/
Изоляция и воспроизводимость
Системный Perl в Debian и Ubuntu нужен пакетному менеджеру: не устанавливайте в него модули и не меняйте версию. Для приложений используйте local::lib, perlbrew или контейнер.
cpanm --installdeps .
carton install
carton exec -- perl bin/report.pl
perl -V:version
Файл cpanfile фиксирует зависимости, carton — их версии; сам Carton ставится через cpanm. Это аналог lock-файла и обязательный элемент, если скрипт работает на нескольких серверах.
Практический сценарий: сводка по логам
Допустим, нужно посчитать коды ответов за несколько дней. Возьмём лог, где поля разделены пробелами: время, код ответа, путь и размер. Конвейер из zcat, Perl и sort решает задачу без промежуточных файлов и внешних библиотек.
zcat access.log.*.gz |
perl -lane '$c{$F[1]}++; END {
print "status $_ $c{$_}" for sort keys %c }' |
sort -k2 -nr | head -20
Здесь -a разбивает строку на поля, -l убирает перевод строки, а блок END печатает накопленную статистику. Такой однострочник понятен коллеге и легко превращается в полноценный скрипт с тестами, когда логика разрастается. Для потоковой обработки не храните весь файл в памяти и не открывайте дескрипторы без закрытия. Если лог пишется постоянно, используйте tail -F и буферизацию вывода.
Проверяйте, что формат полей совпадает с реальным логом: у nginx и Apache разное число полей, а прокси может добавлять свои. Ошибка в индексе даёт правдоподобную, но неверную статистику.
Тесты, производительность и сопровождение
Даже небольшой скрипт выигрывает от тестов. Test::More входит в ядро, prove запускает набор.
use Test::More tests => 2;
is(clean(' a '), 'a', 'trim');
like(format_date('2026-11-06'), qr/^\d{4}-\d{2}-\d{2}$/);
Для профилирования используйте Devel::NYTProf, для поиска утечек — Devel::Cycle. Не оптимизируйте вслепую: сначала измерьте. И обязательно проверяйте входные данные: taint-режим не заменяет валидацию параметров и путей. В CI запускайте prove -l t/ на той же версии Perl, что и в продакшене, иначе различия в модулях проявятся только на сервере.
Итог
Perl в 2026 году — это не музейный язык, а надёжный инструмент для текстов, логов и автоматизации. Пишите с use v5.40, strict и warnings, используйте именованные захваты и построчное чтение, ставьте модули через cpanm в изолированный каталог и покрывайте ключевые функции тестами. Такой код переживёт смену команды и не потребует переписывания через год.