В Perl я могу применить команду 'grep' к данным, которые я захватил, используя оператор триггера напрямую? - PullRequest
0 голосов
/ 02 января 2012

Мне нужно найти «количество» вхождений определенных слов (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 с оператором триггера с точки зрения производительности?

Ответы [ 3 ]

4 голосов
/ 02 января 2012

Это было бы простое решение:

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

(Поскольку вы не предоставляете пример кода, я использовал оператор diamond и предположил, что файл журнала передается в качестве аргумента скрипту.Замените на дескриптор файла, если необходимо.)

grep {/START/../END/} <> создает список элементов внутри и включая разделители, а grep {/particular word/} работает с этим списком.

С точки зрения производительности выбыло бы лучше с

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

Обратите внимание, что вы должны использовать and вместо && или обернуть свое выражение триггера в скобках из-за приоритета оператора.оба:

my $number = grep {/START/../END/ and /particular word/} <>;
1 голос
/ 02 января 2012

Может быть, вы ищете что-то в этом роде:

#!/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'
0 голосов
/ 02 января 2012

Как я могу получить весь текст между 'START' и 'END' в массив и выполнить 'grep' для этого и т. Д.?

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

Также есть«Хорошо» иметь несколько уровней блоков if с оператором триггера с точки зрения производительности?

Пока вы не работаете в НАСА.

...