-2

我需要找到出现在命令输出中的特定单词(C7STH、C7ST2C)的“数量”。该命令以“固定”文本开始和结束 - START & END 如下所示。此命令针对日志文件中的不同节点重复多次。

...

START
SLC ACL PARMG ST                   SDL                             SLI
 0  A1  17    C7STH-1&&-31         MSC19-0/RTLTB2-385
 1  A1  17    C7STH-65&&-95        MSC19-0/RTLTB2-1697

SLC ACL PARMG ST                   SDL                             SLI
 0  A2   0    C7ST2C-4             ETRC18-0/RTLTB2-417
 1  A2   0    C7ST2C-5             ETRC18-0/RTLTB2-449
 2  A2   0    C7ST2C-6             ETRC18-0/RTLTB2-961
...
END

……

我正在使用触发器运算符 (if (/^START$/ .. /^END$/) 来获取每个命令输出。现在

  1. 有没有办法对这些数据进行“grep”而不是逐行进行?就像我可以将 'START' 和 'END' 之间的所有文本放入一个数组并在此等上执行 'grep' 吗?

  2. 从性能的角度来看,使用触发器运算符具有多个级别的 if 块是否“可以”?

4

3 回答 3

4

这将是一个简单的解决方案:

my $number = grep {/particular word/} grep {/START/../END/} <>;

(由于您没有提供代码示例,我使用了菱形运算符并假设日志文件作为参数传递给脚本。如果需要,请替换为文件句柄。)

grep {/START/../END/} <>在分隔符内(包括分隔符)创建一个元素列表,并grep {/particular word/}在该列表上工作。

从性能的角度来看,你会更好

for (<>) {
    $number++ if /START/../END/ and /a/;
}

请注意,由于运算符优先级,您必须使用and而不是&&或将触发器表达式包装在括号中。

结合两者:

my $number = grep {/START/../END/ and /particular word/} <>;
于 2012-01-02T13:53:08.413 回答
1

也许您正在寻找以下方面的东西:

#!/usr/bin/env perl
use strict;
use warnings;
my $word = q(stuff);
my @data;
while (<DATA>) {
    if ( /^START/../^END/ ) {
        chomp;
        push @data, $_ unless /^(?:START|END)/;
    }
    if ( /^END/ ) {
        my $str = "@data";
        print +(scalar grep {/$word/} (split / /,$str)),
            " occurances of '$word'\n";
        @data = ();     
    }
}
__DATA__
this is a line
START of my stuff
more my stuff
and still more stuff
and lastly, yet more stuff
END of my stuff
this is another line
START again
stuff stuff stuff stuff
yet more stuff
END again

...这将输出:

3 occurances of 'stuff'
5 occurances of 'stuff'
于 2012-01-02T14:12:17.483 回答
0

就像我可以将 'START' 和 'END' 之间的所有文本放入一个数组并在此等上执行 'grep' 吗?

(push @ar,$_) if /START/ .. /END/;
grep {/word/ @ar};

从性能的角度来看,使用触发器运算符具有多个级别的 if 块是否“可以”?

只要你不为 NASA 工作。

于 2012-01-02T14:45:27.790 回答