我有一个程序可以将它运行的周期数打印到日志文件中。我想检索日志文件中的最后一个值,以找出运行的循环总数。我正在使用以下代码:
my @cycles = $log =~ /\s+(\d+)\s+Cycles/gsm;
$run{cycles} = $cycles[-1] if @cycles;
是否有一个perl特殊变量存储最后匹配的值,以便我可以使用它而不是收集数组中的循环?
答案 0 :(得分:1)
您可以使用负面预测断言:
($run{cycles}) = $log =~ /\s+(\d+)\s+Cycles(?!.*\s+\d+\s+Cycles)/gsm;
意思是“找到以空格开头的数字序列,后跟空格
和文字Cycles
,后面跟着另一个空格,数字,空格和文字Cycles
“序列。
答案 1 :(得分:1)
我认为这就是你想要的:
my @cycles = $log =~ /\s+(\d+)\s+Cycles/gsm;
$run{cycles} = $+ if @cycles;
请注意,正如暧昧所说,$1
也应该做到这一点(至少它对我有用)。
最后,如果你真的不需要保存数组中的所有循环,但只想要最后一个值,你可以这样做:
($run{cycles}) = $log =~ /.+\s(\d+)\s+Cycles/s;
答案 2 :(得分:1)
我不建议将整个日志文件读入内存,但如果没有关于您正在做什么的更多信息,我就无法编写正确的逐行解决方案。
带有/g
修饰符的正则表达式模式在 next 匹配时停止,因此您只需要while
循环。
请注意,使用/m
或/s
修饰符毫无意义,因为他们只需修改元字符^
,$
和{{}的功能1}}。由于你没有使用这些,它们没有任何效果。
.
答案 3 :(得分:0)
您的问题不完整。您没有显示代码中将日志文件粘贴到$ log中的部分。假设您的日志文件的名称在$ logFile中,那么您的问题是如何改进:
my $log = do { local( @ARGV, $/ ) = $logFile ; <> } ;
my @cycles = $log =~ /\s+(\d+)\s+Cycles/gsm;
$run{cycles} = $cycles[-1] if @cycles;
答案是一次读取一行日志文件:
open my $logFH,'<',$logFile
or die "Could not open $logFile: $!";
my $cycles;
while (my $logLine = <$logFH>) {
($cycles) = $logLine =~ /\s+(\d+)\s+Cycles/;
}
close $logFH;
$run{cycles} = $cycles
if $cycles;
这样你的程序只使用$ logFile中最长行的空格而不是整个文件的空间,以及存储单个Cycle而不是所有文件的空间。
也就是说,I / O的数量相同,但内存使用率要低得多。
您原来的节目是:
该计划是:
答案 4 :(得分:0)
为什么不使用File::ReadBackwards
并采用“第一”匹配线。
$bw = File::ReadBackwards->new( 'log_file' )
or die "can't read 'log_file' $!"
;
while( defined( $log_line = $bw->readline ) ) {
next unless m/\s+(\d+)\s+Cycles/;
print;
last;
}
它应该快一点。