Подтвердить что ты не робот

Как преобразовать однострочные Perl в полные скрипты?

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

Например, я использую следующую команду (из 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

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

4b9b3361

Ответ 1

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

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

выходы:

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

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

Ответ 2

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

-p

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

LINE:
while (<>) {
    ... # your program goes here
} continue {
    print or die "-p destination: $!\n";
}

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

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

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

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

#!/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";
}

Ответ 3

Это очень удобно хранить в script!

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

Параметр -e вводит исполняемый код Perl, который вы можете представить как script в командной строке, поэтому отпустите его и вставьте код в тело. Оставьте -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, использует Perl "magic" (2-argument) open, который специально обрабатывает каналы.

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

$ ~/bin/nagiostime.pl /tmp/other-nagios.log

Ответ 4

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

Кроме того, здесь ваш oneliner как script::)

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

tail -f [email protected] | perl -pe 's/(\d+)/localtime($1)/e'

Ответ 5

#!/usr/bin/env perl

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

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

Ответ 6

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

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

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

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