Ниже приведена программа UNIX grep, написанная на Perl. Хотя она работает медленнее версий, написанных на С (особенно GNU-версии grep), зато обладает многими усовершенствованиями.
Первая и самая важная особенность - эта программа работает везде, где работает Perl. Имеется ряд дополнительных возможностей - tcgrep игнорирует все файлы, кроме простых текстовых; распаковывает сжатые или обработанные утилитой gzip файлы; выполняет просм
Распаковка сжатых файлов выполняется утилитами gzcat или zcat, поэтому данная возможность отсутствует в системах, где эти программы недоступны, а также в системах, не позволяющих запускать внешние программы (например, Macintosh).
При запуске программы без аргументов на экран выводится краткая справка по ее использованию (см. процедуру usage в программе). Следующая командная строка рекурсивно и без учета регистра ищет во всех файлах почтового ящика '/mail сообщения с отправителем "
% tcgrep -ril '"From: .*kate' '/mail Исходный текст программы приведен в примере 6.14.
Пример 6.14. tcgrep
Следующие регулярные выражения показались нам особенно полезными или интересными.
Римские цифры
m/-m.(d?c{0,3}|c[dm])(1^x{0,3}|x[1c])(v?i{0,3}|i[vx])$/i Перестановка двух первых слов
s/(\S+))\s+)(\S+)/$3$2$1/ Ключевое слово = значение
(n/(\w+)\s*=\s*(.*)\s*$/ # Ключевое слово в $1, значение - в $2 Строка содержит не менее 80 символов
т/.{80,}/
мм/дд/гг чч:мм:сс
т|(\d+)/(\d+)/\d+) (\d+):(\d+):(\d+)| Смена каталога
s(/usr/bin)(/usr/local/bin)g Расширение служебных последовательностей %7Е(шестн.)
s/%([0-9A-Fa-f][0-9A-Fa-f])/chr hex 41/ge Удаление комментариев С (не идеальное)
S{
/\* # Начальный ограничитель
.*? # Минимальное количество символов
\*/ # Конечный ограничитель
} []gsx; Удаление начальных и конечных пропусков
s/"\s+//;
s/\s+$//; Преобразование символа \ и следующего за ним п в символ перевода строки
s/\W\n/g; Удаление пакетных префиксов из полностью определенных символов
s/-..::// IP-адрес
m/~[01]Ad\d|2[0-4]\d|25[0-5])\.([01]Ad\d|2[0-4]\d|25[0-5])\. ([01]?\d\d|2[0-4]\d|25[0-5])\.([01]Ad\d|2[0-4]\d|25[0-5])$/; Удаление пути из полного имени файла
sC-../Ю
Определение ширины строки с помощью TERMCAP
$cols = ( ($ENV{TERMCAP} || " oo) =~ m/:coff(\d+):/ ) ? $1 : 80: Удаление компонентов каталогов из имени программы и аргументов
($name = join(" ", map { s,"\S+/,,; $_ } ($0 @ARGV)); Проверка операционной системы
die "This isn't Linux" unless $"0 =~m/linux/i; Объединение строк в многострочных последовательностях
s/\n\s+/ /g; Извлечение всех чисел из строки
@nums = m/(\d+\.'''\d*|\.\d+)/g; Поиск всех слов, записанных символами верхнего регистра
@capwords = m/(\b[~\Wa-zO-9_]+\b)/g; Поиск всех слов, записанных символами нижнего регистра
@capwords = m/(\b["\WA-ZO-9_]+\b)/g; Поиск всех слов, начинающихся с буквы верхнего регистра
(Sicwords = m/(\b["\Wa-zO-9_]["\WA-ZO-9_]*\b)/;
@links = m/]+7HREF\s*=\s*['"]?(["'" >]^)[ "o]?>/sig; Поиск среднего инициала в $_
$initial = m/"\S+\s+(\s)\S*\s+\S/ ? $1 : ""; Замена кавычек апострофами
s/"([-"]*)V"$r7g Выборка предложений (разделитель - два пробела)
{ local $/ = "";
while (о) { s/\n/ /g;
s/ <3,}/ /g;
push ^sentences, m/(\S.*?[!?.])(?= |\Z)/g;
}
}
ГГГГ-ММ-ДД
m/(\d{4})-(\d\d)-(\d\d)/ # ГГГГ в $1, MM в $2 и ДД в $3 Выборка строк независимо от терминатора (завершающего символа)
push(@lines, $1)
while ($input =~ s/~(["\012\015]*)(\012\015?|\015\012?)//);