複数行から情報を収集する方法は?

複数行から情報を収集する方法は?

次のデータを含むログファイルがあります。

2019-02-11 00:05:58.241 [exec-178] Start request
2019-02-11 00:05:58.242 [exec-178] customer_name
2019-02-11 00:05:58.243 [exec-178] other process
2019-02-11 00:05:58.244 [exec-178] other process
2019-02-11 00:05:58.245 [exec-178] results
2019-02-11 00:05:58.246 [exec-178] End request (13ms)

単一のgrepコマンドを使用して「customer_name」と「End request」をキャプチャしたいと思います。使用しようとしましたが、grep -E "[0-9]{2,4}ms期待した結果は出ません。

予想出力:

2019-02-11 00:05:58.242 [exec-178] customer_name 
2019-02-11 00:05:58.246 [exec-178] End request (13ms)

答え1

grepを使用してgrep -E見つけることができるパターンは、パイプ記号で区切られています。

[root@server ~]# grep -Ei "customer_name|end request" file 
2019-02-11 00:05:58.242 [exec-178] customer_name
2019-02-11 00:05:58.246 [exec-178] End request (13ms)
[root@server ~]# 

抜粋man grep:

-E、--extended-regexp PATTERNを拡張正規表現(ERE、以下を参照)として解釈します。

-i、--ignore-case PATTERNと入力ファイルの大文字と小文字の違いを無視します。

答え2

固定文字列検索を使用するgrepのは非常に簡単です。grep次のオプションを使用して複数のスキーマを渡すことができます-e

$ cat testfile
2019-02-11 00:05:58.241 [exec-178] Start request
2019-02-11 00:05:58.242 [exec-178] customer_name
2019-02-11 00:05:58.243 [exec-178] other process
2019-02-11 00:05:58.244 [exec-178] other process
2019-02-11 00:05:58.245 [exec-178] results
2019-02-11 00:05:58.246 [exec-178] End request (13ms)

$ grep -F -e 'customer_name' -e 'End request' testfile
2019-02-11 00:05:58.242 [exec-178] customer_name
2019-02-11 00:05:58.246 [exec-178] End request (13ms)

この-Fオプションは、固定文字列を検索することを指定します。これは必ずしも必要ではありませんが、コマンドをより明確にするのに役立ちます。

拡張正規表現を使用して簡単にコマンドを実行することもできます。 A | B式は「A」または「B」を検索します。

$ grep -E 'customer_name|End request' testfile
2019-02-11 00:05:58.242 [exec-178] customer_name
2019-02-11 00:05:58.246 [exec-178] End request (13ms)

答え3

別の行にある正確な文字列を返したい場合:

egrep -o "customer_name|End request" logfile

出力:

customer_name
End request

行全体を返すには、次のようにします。

egrep "customer_name|End request" logfile

出力

2019-02-11 00:05:58.242 [exec-178] customer_name
2019-02-11 00:05:58.246 [exec-178] End request (13ms)

答え4

検索行間(および含む)のすべての内容を取得するには、awkを使用します。

awk 'BEGIN {found=0}; /customer_name/ {found=1}; found {print}; /End request/ {found=0}' logfile

"customer_name"が静的文字列ではなく別の値である場合は、-v次のようにしてみてください。

awk -v "name=sally" 'BEGIN {found=0}; index($0, name) {found=1}; found {print}; /End request/ {found=0}' logfile

または、より良い形式と説明がありますが、コピーして貼り付けるのは難しいです。

awk -v "name=sally" 'BEGIN {
        # good style, but optional... nonexistent variables are already 0
        found=0;
    };
    index($0, name) {
        # remember that we found the first line
        found=1;
    }; 
    found {
        # since we print after the found=1, we print that line
        # and also the lines between
        # and since we set found=0 after already printing the end line, we are printing that too
        print;
    }; 
    /End request/ {
        # mark that we stop printing
        found=0;
    };' logfile

関連情報