我有一个grep命令,它在Linux命令提示符下工作:grep -Po 'rand_num=\K[^ ]*' log.txt
这个命令在我的log.txt文件中打印rand_num=
后面的数字。但是我需要在perl脚本中使用这个命令。我试过了
my $rand_number;
$rand_number = system("grep -Po 'rand_num=\K[^ ]*' log.txt");
print "Random number = $rand_number";
但是不行我试过$rand_number =
grep -Po 'rand_num=\K[^ ]*' log.txt;
也不行
有人能告诉我这里出了什么问题吗?怎么让它工作的?
2条答案
按热度按时间7kqas0il1#
一旦进入Perl脚本,就不需要到系统中运行外部命令(它使用Perl的regex!)--Perl可以做得非常好,甚至更好。
以下是一些方法。
打开一个文件,逐行阅读,从每一行中提取所需的短语
或者一次读取所有行,然后将它们通过排序过滤器
我使用map从每一行中提取短语,因为grep将返回满足条件的整行。如果没有匹配,则返回空列表,“消失”到
map
的整个返回列表中,如果没有匹配,则“消失”到未初始化的数组中。这样,map
就充当了过滤器。如果一行可以有多个
rand_num=NUM
,那么上面的代码会从每一行的所有rand_num=NUM
中获取(假定为†)数字,如果还假定文件名$file
已经被读入脚本。或者,使用“null”文件句柄(不需要文件名)
如果在命令行上使用该文件名
script.pl file
调用该脚本,则为。这是因为“magic”diamond运算符(
<>
)逐行读取命令行上提交的文件。尽管如此,如果脚本以script.pl file1 file2 ...
运行,它将对所有这些文件执行上述操作。也可以将整个文件读入一个字符串(“slurp”),然后使用它。当感兴趣的模式跨越多行时,这很有帮助。
现在,正则表达式匹配被绑定到
slurp
方法返回的字符串,该字符串包含整个文件。由于这是在列表上下文中完成的,通过列表赋值将其强加给正则表达式,因此所有匹配都在列表中返回,该列表被赋值给@rn
。我大胆地假设您的(every)脚本以
对于feature
say
,我们还需要use feature 'say';
或use
,一个包含它的Perl版本或另一个包含它的大型框架。†问题中的正则表达式匹配
rand_num=
后面的所有非空格字符,如果绝对确定这些字符只能是预期的数字,那就这样吧。否则,可以更小心地使用只匹配实际数字的模式。或者,如上所述捕获,然后使用
looks_like_number
从Scalar::Util检查它是否确实是数字uhry853o2#
Perl将
\K
视为转义序列,并删除了system
看到的实际字符串中的反斜杠。也可以使用Perl的多种方法之一编写一个字符串,完全禁止反斜杠扩展。
这看起来可能很奇怪,如果您的编辑器不是为Perl设计的,它可能也不理解它(老实说,我很惊讶StackOverflow的代码高亮器能正确处理它)。但是
q(...)
等效于'...'
,只是您可以在前者内部使用单引号。