Как я могу преобразовать остроты Perl в полные сценарии?

Я нахожу много острот Perl онлайн. Иногда я хочу преобразовать эти остроты в сценарий, потому что иначе я забуду синтаксис остроты.

Например, я использую следующую команду (из nagios.com):

tail -f /var/log/nagios/nagios.log | perl -pe 's/(\d+)/localtime($1)/e'

Я был бы для замены его чем-то вроде этого:

tail -f /var/log/nagios/nagios.log | ~/bin/nagiostime.pl

Однако я не могу выяснить лучший способ быстро бросить этот материал в сценарий. У кого-либо есть быстрый способ бросить эти остроты в сценарий Perl или Bash?

17
задан brian d foy 16 May 2010 в 00:11
поделиться

6 ответов

Вы можете преобразовать любое однострочное предложение Perl в полноценный сценарий, пропустив его через B::Deparse бэкенд компилятора, который генерирует исходный код Perl:

perl -MO=Deparse -pe 's/(\d+)/localtime($1)/e'

outputs:

LINE: while (defined($_ = <ARGV>)) {
    s/(\d+)/localtime($1);/e;
}
continue {
    print $_;
}

Преимущество этого подхода перед расшифровкой флагов командной строки вручную заключается в том, что именно так Perl интерпретирует ваш сценарий, поэтому нет никаких догадок. B::Deparse является модулем ядра, поэтому устанавливать ничего не нужно.

38
ответ дан 30 November 2019 в 10:14
поделиться

Взгляните на perlrun :

-p

заставляет Perl выполнять следующий цикл вокруг вашей программы, который заставляет его перебирать аргументы имени файла наподобие sed:

 LINE: 
while (<>) {
 ... # здесь идет ваша программа 
} continue {{{1 }} print or die "-p destination: $! \ n"; 
} 
 

Если файл, названный аргументом, не может быть открыт по какой-либо причине, Perl предупреждает вас об этом, и переходит к следующему файлу.Обратите внимание, что линии печатаются автоматически. Ошибка, возникающая во время печати, считается фатальной. Чтобы подавить печать, используйте переключатель -n. -P отменяет переключатель -n.

Блоки BEGIN и END могут использоваться для захвата управления до или после неявного цикла, как в awk.

Итак, просто возьмите этот кусок кода, вставьте свой код в строку «# ваша программа идет сюда», и альт, ваш скрипт готов!

Таким образом, это будет:

#!/usr/bin/perl -w
use strict; # or use 5.012 if you've got newer perls

while (<>) {
    s/(\d+)/localtime($1)/e
} continue {
    print or die "-p destination: $!\n";
}
8
ответ дан 30 November 2019 в 10:14
поделиться

Здесь есть несколько хороших ответов, если вы хотите сохранить однострочный сценарий и, возможно, даже расширить его, но самая простая вещь, которая могла бы сработать, это просто:

#!/usr/bin/perl -p
s/(\d+)/localtime($1)/e

Perl распознает параметры в hashbang в строке сценария, поэтому вместо того, чтобы полностью писать цикл, вы можете просто продолжить выполнение неявного цикла с -p.

Но написав цикл явно и используя -w и "use strict;" хороши, если вы планируете использовать его в качестве отправной точки для написания более длинного сценария.

3
ответ дан 30 November 2019 в 10:14
поделиться

Этот действительно легко хранить в скрипте!

#! /usr/bin/perl -p
s/(\d+)/localtime($1)/e

Опция -e вводит код Perl для выполнения - который можно рассматривать как сценарий в командной строке - поэтому отбросьте ее и поместите код в тело. Оставьте -p в строке shebang (#! ).

В целом, безопаснее всего придерживаться не более одного "блока" опций в строке shebang. Если вам нужно больше, вы всегда можете бросить их эквиваленты в блок BEGIN {}.

Не забудьте chmod +x ~/bin/nagiostime.pl

Вы можете стать немного вычурнее и встроить часть tail:

#! /usr/bin/perl -p

BEGIN {
  die "Usage: $0 [ nagios-log ]\n" if @ARGV > 1;
  my $log = @ARGV ? shift : "/var/log/nagios/nagios.log";
  @ARGV = ("tail -f '$log' |");
}

s/(\d+)/localtime($1)/e

Это работает, потому что код, написанный за вас -p, использует "волшебный" (2-аргументный) open Perl, который специально обрабатывает трубы.

Без аргументов он преобразует nagios.log, но вы также можете указать другой файл журнала, например, ,

$ ~/bin/nagiostime.pl /tmp/other-nagios.log
7
ответ дан 30 November 2019 в 10:14
поделиться
#!/usr/bin/env perl

while(<>) {
    s/(\d+)/localtime($1)/e;
    print;
}

Цикл while и печать - это то, что -p делает автоматически за вас.

3
ответ дан 30 November 2019 в 10:14
поделиться

У Роберта есть «настоящий» ответ выше, но он не очень практичный. Переключатель -p творит немного волшебства, а другие параметры обладают еще большей магией (например, проверьте логику флага -i). На практике я бы просто создал псевдоним / функцию bash для обтекания единственной строки, а не преобразовывал ее в скрипт.

В качестве альтернативы, вот ваш единственный лайнер в виде скрипта: :)

#!/usr/bin/bash
# takes any number of arguments: the filenames to pipe to the perl filter

tail -f $@ | perl -pe 's/(\d+)/localtime($1)/e'
4
ответ дан 30 November 2019 в 10:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: