Глава 18В этой главе:
Преобразование sed-программ в Perl-программы Преобразование shell-сценариев в Perl-программы Упражнение Преобразование других программ в Perl-программыПреобразование awk-программ в Perl-программы Одна из самых замечательных особенностей Perl состоит в том, что он представляет собой семантическое надмножество (как минимум) языка awk. С практической точки зрения зто значит, что если вы можете сделать что-либо в awk, вы сможете сделать зто и в Perl. При зтом, однако, Perl не обладает синтаксической совместимостью с awk. Например, переменная NR (номер входной записи) awk представляется в Perl как $.Если у вас сть а^-программа и вы хотите выполнить ее Perl-вариант, можно осуществить механическое Преобразование зтой программы с помо-щью утилиты а2р, которая сть в дистрибутиве Perl. Зта утилита конвертирует синтаксис awk в синтаксис Perl и может создать непосредственно выполняе-мый Perl-сценарий для подавляющего большинства ои^-программ.Чтобы воспользоваться утилитой а2р, поместите свою aw/^-программу в отдельный файл и вызовите а2р с именем зтого файла в качестве аргумента или переадресуйте стандартный ввод а2р на ввод из зтого файла. В результате на стандартном виводе а2р вы получите нормальную Perl-программу. Например:$ cat myawkprog Bb.SIN { sum = 0 ) /llama/ ( sum += $2 ) END { print "The llama count is " sum } $ a2p <myawkprog >myperlprog $ perl myperlprog somefile The llama count is 15 $ Можно также направить стандартний вывод a2p прямо в Perl, потому что интерпретатор Perl принимает программу со стандартного ввода, если полу-чает такое указание:$ a2p <myawkprog I perl - somefile The llama count is 15 $ Преобразованный для использования в Perl aw^-сценарий, как правило, выполняет идентичную функцию, часто с большей скоростью й, конечно, без каких-либо присущих awk ограничений на длину строки, количество параметров и т.д. Некоторые преобразованные Perl-программы могут выпол-няться медленнее; Perl-действие, зквивалентное данной awA-операции, не обязательно будет самым зффективным Perl-кодом, по сравнению с напи-санным вручную.Вы, возможно, захотите оптимизировать Преобразованный Perl-код или добавить в Perl-версию программы новьге функциональные возможности. Зто сделать довольно просто, поскольку полученный Perl-код читается достаточно легко (учитывая, что перевод выполняется автоматически, сле-дует отметить зто как большое достижение). В некоторых случаях перевод не выполняется механически. Например, сравнение "меньше чем" и для чисел, и для строк в awk выражается операцией <. В Perl для строк используется it, а для чисел операция <. В большинстве случаев awk, как и утилита a2p, делает разумное предполо-жение относительно числового или строкового характера двух сравниваемых значений. Однако вполне возможно, что о каких-нибудь двух значеннях будет известно недостаточно много для того, чтобы определить, какое должно выполняться сравнение числовое или строковое, позтому a2p использует наиболее вероятную операцию и помечает возможно ошибочную строку знаками #?? (Perl-комментарием) и пояснением. После преобразо-вания обязательно просмотрите результат на предмет наличия таких коммен-тариев и проверьте сделанные предположения. Более подробно о работе утилиты a2p рассказывается на ее man-странице. Если зтой утилиты в том каталоге, откуда вы вызываете Perl, нет, громко пожалуйтесь тому, кто инсталлировал вам Perl.Преобразование sed-программ в Perl-программыМожет быть, вам покажется, что мы повторя мся, но угадайте, что мы сейчас скажем? А вот что: Perl семантическое надмножество не только awk, но и sed.С дистрибутивом поставляется конвертор sed-Рет , который называется s2p. Как и а2р, s2p получает со стандартного ввода ,уе</-сценарий и направляет на стандартний вывод Perl-программу. В отличие от результата работы а2р, преобразованная программа редко ведет себя не так, как нужно, позтому вы вполне можете рассчитывать на ее нормальную работу (при отсутствии дефектов в самой s2p или Perl).Конвертированные 5 й/-программы могут работать быстрее или медлен-нее оригинала. Как правило, они работают значительно быстрее (благодаря хорошо оптимизированным Perl-программам обработки регулярних виражений). Конвертированный waf-сценарий может работать с опцией -п или без нее. Опция -п имеет тот же смысл, что и соответствующий ключ для sed. Чтобы воспользоваться зтой опцией, конвертированный сценарий должен направить сам себя в препроцессор С, а зто несколько замедляет запуск. Если вы зна те, что всегда будете вызывать конвертированный wdf-сценарий с опцией -п или без нее (например, при преобразовании wfif-сценария, используемого в больших shell-программах с известными аргументами), вы можете информировать утилиту s2p об зтом (посредством ключей -п и -р), и она оптимизирует сценарий под выбранный вами ключ.В качестве примера, демонстрирующего високую универсальность и мощь языка Perl, отметим тот факт, что транслятор s2p написан на Perl. Если вы хотите увидеть, как Ларри программирует на Perl, взгляните на зтот транслятор только сначала сядьте, чтобы не упасть (даже с учетом того, что зто очень древний код, относительно не изменившийся с версии 2).Преобразование shell-сценариев в Perl-программы Вы, наверное, подумали, что речь пойдет о конверторе, осуществляющем Преобразование shell-сценариев в Perl-программы? А вот и нет. Многие спрашивают о такой программе, но проблема в том, что большинство из того, что делает сценарий, делается отнюдь не им самим. Большинство сценариев shell тратят практически все сво время на вызовы отдельных программ для извлечения фрагментов строк, сравнения чисел, конкатенации файлов, удаления каталогов и т.д. Преобразование такого сценария в Perl требовало бы понимания принципа работы каждой из вызываемых утилит или перекладывания вызова каждой из них на плечи Perl, что абсолютно ничего не дает.Позтому лучшее, что вы можете сделать, ~ зто посмотреть на сценарий shell, определить, что он делает, и начать все с нуля, но уже на Perl. Конечно, вы можете провести на скорую руку транслитерацию поместив основные части исходного сценария в вызовы system () или заключив их в обратные кавычки. Возможно, вам удастся заменить некоторые операции командами Perl: например, заменить system(rm /red) на unlink (fred) или цикл for shell на такой же цикл Perl. В большинстве случаев, однако, вы увидите, что зто несколько напоминает конвертирование программы, написанной на Коболе, в С (почти с тем же уменьшением количества символов й, как следствие, повышением степени неразборчивости текста программы).Упражнение 1. Преобразуйте следующий сценарий shell в Perl-программу: cat /etc/passwd I awk -F: '(print $1, $6(' | while read user home do newsrc="$home/.nevsrc" if [ -r $newsrc ] then if grep -s echo -n "$user is a good person, "; echo "and reads comp.lang.perl.announce!" fi fi done |