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是一个核心模块,因此无需安装.
看看perlrun:
-p
导致Perl假定你的程序周围有以下循环,这使得它迭代文件名参数有点像sed:
Run Code Online (Sandbox Code Playgroud)LINE: while (<>) { ... # your program goes here } continue { print or die "-p destination: $!\n"; }如果由于某种原因无法打开由参数命名的文件,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)
那个脚本真的很容易存放!
#! /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