Как выполнить многострочный grep для нескольких файлов?

Как выполнить многострочный grep для нескольких файлов?

Я пытаюсь выхватить этот шаблон, где бы он ни встречался в нескольких файлах журнала (Примечание: эти шаблоны могут сильно различаться по размеру, т. е. по количеству Blahs):

   Found an txt File
    Blah
    Blah
    10019874
    Blah
    Blah
    Processed File   

Используя эту командную строку:

 pcregrep -M 'Found an.*(\n|.)*10019874.*(\n|.)*Processed' log_*.txt

Мое регулярное выражение провереноРЕГУЛЯРНОЕ ВЫРАЖЕНИЕ ЗДЕСЬ

Я использую pcregrep с флагом -M multiline. Он будет в любых файлах журнала, которые начинаются с 'log_' и заканчиваются '.txt'. Когда я запускаю эту команду, она возвращает 'Segmentation Fault'

Есть ли более простой/лучший способ сделать это?

решение1

Как я уже сказал в своем комментарии, команда, которую вы разместили, отлично работает на моем LMDE (pcregrep версии 8.31 2012-07-06). Однако, поскольку ваше регулярное выражение определяет только часть строки, которую вы ищете, вы также можете сделать это с помощью normal grep:

grep -A 6 'Found an' log_*.txt | grep -C 3 10019874

будет -A 6напечатана строка, соответствующая переданной строке, и 6 следующих строк, а также -C 3будет напечатано 3окружающийлинии. Конечный результат точно такой же, как и при pcregrepподходе, который вы использовали.


Если ваш шаблон может иметь разное количество строк, это может объяснить segfault. Предположительно, в некоторых ваших файлах совпадающий раздел слишком длинный и вызывает ошибку нехватки памяти. Одним из способов обойти это будет небольшой скрипт:

perl -ne '$c=1 if /Found an/; ## set $c to 1 if this line matches 'Found on'
          if($c){               ## If $c is defined and non-0
            push @F,$_;         ## Add the current line to the @F array
            $c++ if /10019874/; ## Increment $c if this line matches '10019874'
            if(/Processed/){    ## If this line matches 'Processed'
                print "@F" if $c>1; ## Print the contents of @F if $c is >1
                @F=""; $c=0;         ## Empty @F, set $c to 0.
            }
           }' log_*.txt 

То же самое, что и однострочник:

perl -ne '$c=1 if /Found an/; if($c){push @F,$_; $c++ if /10019874/; if(/Processed/){print "@F" if $c>1; @F=""; $c=0;}}' log_*txt 

Связанный контент