如何将Perl单行转换为完整脚本?

Ste*_*ski 17 perl command-line

我在网上发现了很多Perl单行.有时我想将这些单行转换成脚本,否则我会忘记单行的语法.

例如,我正在使用以下命令(来自nagios.com):

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

我要用这样的东西替换它:

tail -f /var/log/nagios/nagios.log | ~/bin/nagiostime.pl
Run Code Online (Sandbox Code Playgroud)

但是,我无法找出将这些内容快速抛入脚本的最佳方法.有没有人能够快速将这些单行内容放入Bash或Perl脚本中?

Eri*_*rom 38

您可以将任何Perl one-liner转换为完整脚本,方法是将其传递给B::Deparse生成Perl源代码的编译器后端:

perl -MO=Deparse -pe 's/(\d+)/localtime($1)/e'
Run Code Online (Sandbox Code Playgroud)

输出:

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

这种方法比手动解码命令行标志的优点是,这正是Perl解释脚本的方式,所以没有猜测. B::Deparse是一个核心模块,因此无需安装.


Rob*_*t P 8

看看perlrun:

-p

导致Perl假定你的程序周围有以下循环,这使得它迭代文件名参数有点像sed:

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

如果由于某种原因无法打开由参数命名的文件,Perl会向您发出警告,然后转到下一个文件.请注意,线条会自动打印.打印期间发生的错误被视为致命错误.要禁止打印,请使用-n开关.-p覆盖-n开关.

BEGIN和END块可用于在隐式循环之前或之后捕获控制,就像在awk中一样.

所以,只需要获取这段代码,在"#your program goes here"行中插入您的代码,并且中提琴,您的脚本就准备好了!

因此,它将是:

#!/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";
}
Run Code Online (Sandbox Code Playgroud)


Gre*_*con 7

那个脚本真的很容易存放!

#! /usr/bin/perl -p
s/(\d+)/localtime($1)/e
Run Code Online (Sandbox Code Playgroud)

-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
Run Code Online (Sandbox Code Playgroud)

这是有效的,因为为您编写的代码-p使用Perl的"魔法"(2参数)open来专门处理管道.

没有参数,它会转换nagios.log,但您也可以指定不同的日志文件,例如,

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