複数のファイルにわたって複数行の grep を実行するにはどうすればよいでしょうか?

複数のファイルにわたって複数行の grep を実行するにはどうすればよいでしょうか?

複数のログ ファイルのどこでこのパターンが発生しても、それを取得しようとしています (注: これらのパターンはサイズ、つまり Blah の数が大きく異なる場合があります)。

   Found an txt File
    Blah
    Blah
    10019874
    Blah
    Blah
    Processed File   

このコマンド ラインを使用する:

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

私の正規表現は正しい正規表現はこちら

私は -M マルチライン フラグ付きの pcregrep を使用しています。これは、'log_' で始まり '.txt' で終わるすべてのログ ファイルで有効になります。このコマンドを実行すると、'Segmentation Fault' が返されます。

これを行うより簡単な/良い方法はありますか?

答え1

コメントで述べたように、投稿されたコマンドは私の LMDE (pcregrep バージョン 8.31 2012-07-06) では正常に動作します。ただし、正規表現では探している文字列の一部のみを指定しているため、通常の方法でこれを行うこともできますgrep

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

-A 6渡された文字列に一致する行とそれに続く6行を出力し、は-C 33行目を出力します。周囲の行。最終結果は、pcregrep使用していたアプローチとまったく同じになります。


パターンの行数が異なる場合、セグメント違反の原因となる可能性があります。おそらく、一部のファイルでは、一致するセクションが長すぎてメモリ不足エラーが発生します。回避策の 1 つは、スクリプトを少し作成することです。

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 

関連情報