Как мне указать код "before-the loop" при использовании "perl -ne"? - PullRequest
2 голосов
/ 12 ноября 2010

Как мне указать код "before-the loop" при использовании "perl -ne", не прибегая к блокам BEGIN / END или заменяя "-n" на фактически записанный цикл while?

Чтобы объяснить подробно:

Скажем, у меня есть следующий код Perl:

use MyModule;
SETUP_CODE;
while (<>) {
    LOOP_CODE;
}
FINAL_CODE;

Как я могу заменить его однострочным использованием perl -ne?

Конечно, часть цикла обрабатывается самим -n, тогда как FINAL_CODE можно сделать, используя хитрость добавления "} { FINAL_CODE" в конце;тогда как оператор use может быть обработан с помощью параметра "-M".

Итак, если бы у нас не было SETUP_CODE до цикла, я мог бы написать следующее:

perl -MMyModule -ne 'LOOP_CODE } { FINAL_CODE'

Но как мы можем вставить SETUP_CODE здесь?

Единственная идея, которую я имею, состоит в том, чтобы попытаться добавить ее после цикла через блок BEGIN{}, ala

perl -MMyModule -ne 'LOOP_CODE } BEGIN { SETUP_CODE } { FINAL_CODE'

Но это кажется в лучшем случае хакерским.

Любой другойрешение?

Просто чтобы прояснить ситуацию - я уже знаю Я могу сделать это, записав цикл while вместо использования "-n" или используя BEGIN /END блокирует (и может даже согласиться с тем, что с определенных точек зрения делать «время», вероятно, лучше).

Меня интересует, есть ли другое решение.

Ответы [ 6 ]

6 голосов
/ 12 ноября 2010

Пишите BEGIN и END блоки без церемонии:

$ perl -lne 'BEGIN { print "hi" }
             print if /gbacon/;
             END { print "bye" }' /etc/passwd
hi
gbacon:x:700:700:Greg Bacon,,,:/home/gbacon:/bin/bash
bye
4 голосов
/ 12 ноября 2010

Вставьте ваш дополнительный код в опцию -M

perl -M'Module;SETUP CODE' -ne 'LOOP CODE'

$ perl -MO=Deparse -M'MyModule;$SETUP=1' -ne '$LOOP=1}{$FINAL=1'
use MyModule;
$SETUP = 1;
LINE: while (defined($_ = <ARGV>)) {
    $LOOP = 1;
}
{
    $FINAL = 1;
}
-e syntax OK
2 голосов
/ 12 ноября 2010

Поместите ваш дополнительный код в модуль и используйте ‑M.Это будет работать до цикла.

Возможно, вам даже удастся проникнуть внутрь через $ENV{PERL5OPT}, хотя переключатели довольно ограничены;например, нет ‑e или ‑E.

Полагаю, вы могли бы сделать что-то возмутительное и с $ENV{PERL_ENCODING}, если бы вы действительно этого хотели.

Это вся Acme:: территория. Пожалуйста, не надо.101

РЕДАКТИРОВАТЬ: Решение only , которое мне очень нравится, очень не креативное и абсолютно простое INIT{}.

1 голос
/ 12 ноября 2010

Может быть, есть какой-то неясный способ добиться этого с -ne, но да, гораздо проще просто использовать perl -e и код в while(<>) самостоятельно.

1 голос
/ 12 ноября 2010

Удалите -n и добавьте while (<>) { ... }. Какие? Это короче и проще, чем вещь BEGIN.

0 голосов
/ 12 ноября 2010

В командной строке может быть несколько ключей -e.

Предполагается, что тест содержит

1
2
3
4

perl -e '$a=5;' -ne '$b+=$_ + $a}{print "$b\n"' test

напечатает 30.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...