我正在尝试使用perl从日志文件中grep多个模式。对于第一个模式,我通过只读变量($1,$2..)获得所需的匹配模式。但是对于下一个模式,只读变量将返回前一个值,而不是与第二个模式匹配的值。
代码如下:
  $tmp = `grep "solo_video_channel_.*(0): queueing" $log`;
  chomp($tmp);
  $tmp =~ m/(.*):.*solo_video_channel_write(.*): queueing page (.*).*/;
  $chnl = $2;
  $page = $3;
  $timestamp = $1;
  $tmp1 = `grep "(0): DUMP GO" $log`;
  chomp($tmp1);
  $tmp1 =~ m/(.*): solo_video_channel_write(0): DUMP GO/;
  $dmp = $1;
  print "dump go time = $1\n";在grep之后,tmp1的值如期而至。但1美元的价值与前一个相同。有什么建议吗?
发布于 2014-10-15 23:25:19
始终确保在使用捕获的变量之前验证正则表达式匹配。
此外,没有理由向grep付出代价。改用Perl的文件处理:
use strict;
use warnings;
local @ARGV = $log;
while (<>) {
    chomp;
    if (/solo_video_channel_.*\(0\): queueing/) {
        if ( my ( $timestamp, $chnl, $page ) = m/(.*):.*solo_video_channel_write(.*): queueing page (.*).*/ ) {
            print "$. - $timestamp, $chnl, $page\n";
        }
    }
    if ( my ($dmp) = m/(.*): solo_video_channel_write\(0\): DUMP GO/ ) {
        print "dump go time = $dmp\n";
    }
}请注意,您的第一组if几乎肯定可以合并到单个if语句中,但我暂时保留了它。
发布于 2014-10-15 22:58:29
在第二个regexp中,您需要转义文字括号
$tmp1 =~ m/(.*): solo_video_channel_write\(0\): DUMP GO/这是因为表达式\(0\)与模式(0)完全匹配
在此答案中给出的示例中,这将包括以下字符串
37: solo_video_channel_write(0): DUMP GO相反,表达式(0)与模式0完全匹配,并设置捕获组。
使用原始问题中给出的regexp
$tmp1 =~ m/(.*): solo_video_channel_write(0): DUMP GO/;匹配将发生在字符串上,例如
37: solo_video_channel_write0: DUMP GO当然,在原始程序中,字符串不是这种格式,因此它们不匹配,并且没有设置$1
外壳程序grep的正则表达式语法与使用圆括号设置捕获组不同(令人困惑),它们必须用反斜杠进行转义,这与perl中的语法相反
发布于 2014-10-15 23:34:48
为什么不使用Pure Perl呢?它比运行外部greps更快。另外,您可以一次对两个正则表达式进行grep。比遍历文件两次更快。
始终检查rexp匹配的值。在这里,我使用if语句来实现这一点。还要注意,我打印的是与UNMATCHED LINES不匹配的所有行。您可以在看到一切正常时删除else,或者简单地重定向2> /dev/null。
use strict;
use warnings;
use autodie;
use feature qw(say);
my $log = "log.txt";
open my $log_fh, "<", $log;
while ( my $line = <$log_fh> ) {
    my $timestamp;
    my $channel;
    my $page;
    my $gotime;
    if    ( $line =~ /(.*):.*solo_video_channel_(.*):\s+queueing page (.*)/ ) {
        $timestamp = $1;
        $channel = $2;
        $page = $3;
        say qq(Timestamp = "$timestamp"  Channel = "$channel"  Page = "$page");
    }
    elsif ( $line =~ /(.*): solo_video_channel_write(0): DUMP GO/ ) {
        $gotime = $1;
        say "Dump Go Time = $1";
    }
    else {
        say STDERR qq(UNMATCHED LINES: "$line");
    }
}
close $log_fh;https://stackoverflow.com/questions/26385403
复制相似问题