首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用perl的Grep

使用perl的Grep
EN

Stack Overflow用户
提问于 2014-10-15 22:43:38
回答 3查看 133关注 0票数 0

我正在尝试使用perl从日志文件中grep多个模式。对于第一个模式,我通过只读变量($1,$2..)获得所需的匹配模式。但是对于下一个模式,只读变量将返回前一个值,而不是与第二个模式匹配的值。

代码如下:

代码语言:javascript
运行
复制
  $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美元的价值与前一个相同。有什么建议吗?

EN

回答 3

Stack Overflow用户

发布于 2014-10-15 23:25:19

始终确保在使用捕获的变量之前验证正则表达式匹配。

此外,没有理由向grep付出代价。改用Perl的文件处理:

代码语言:javascript
运行
复制
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语句中,但我暂时保留了它。

票数 2
EN

Stack Overflow用户

发布于 2014-10-15 22:58:29

在第二个regexp中,您需要转义文字括号

代码语言:javascript
运行
复制
$tmp1 =~ m/(.*): solo_video_channel_write\(0\): DUMP GO/

这是因为表达式\(0\)与模式(0)完全匹配

在此答案中给出的示例中,这将包括以下字符串

代码语言:javascript
运行
复制
37: solo_video_channel_write(0): DUMP GO

相反,表达式(0)与模式0完全匹配,并设置捕获组。

使用原始问题中给出的regexp

代码语言:javascript
运行
复制
$tmp1 =~ m/(.*): solo_video_channel_write(0): DUMP GO/;

匹配将发生在字符串上,例如

代码语言:javascript
运行
复制
37: solo_video_channel_write0: DUMP GO

当然,在原始程序中,字符串不是这种格式,因此它们不匹配,并且没有设置$1

外壳程序grep的正则表达式语法与使用圆括号设置捕获组不同(令人困惑),它们必须用反斜杠进行转义,这与perl中的语法相反

票数 1
EN

Stack Overflow用户

发布于 2014-10-15 23:34:48

为什么不使用Pure Perl呢?它比运行外部greps更快。另外,您可以一次对两个正则表达式进行grep。比遍历文件两次更快。

始终检查rexp匹配的值。在这里,我使用if语句来实现这一点。还要注意,我打印的是与UNMATCHED LINES不匹配的所有行。您可以在看到一切正常时删除else,或者简单地重定向2> /dev/null

代码语言:javascript
运行
复制
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;
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26385403

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档