sedを使用して潜在的な複数行ログエントリを選択する

sedを使用して潜在的な複数行ログエントリを選択する

sed私はアプリケーションサーバーログから個々のログエントリを選択するコマンドを思い出そうとしました。

ログの形式は次のとおりです。

LOG|2016-07-26_15:37:45:536|entry1|!
LOG|2016-07-26_15:37:45:536|entry2|extra data
on new line|!
LOG|2016-07-26_15:37:45:536|entry3|!
LOG|2016-07-26_15:37:45:536|entry4|!
LOG|2016-07-26_15:37:45:536|entry5|!

ご覧のとおり、一部の項目には行が 1 つだけあり、一部の項目には追加データを含む複数の行があります。エントリは常にログタイプ(上記の「LOG」で単純化されています)で始まり、常に次に始まります。|!

今これが私が今まで持っているものです:

sed -n -e '/'$id'/,/|!/ p'

これは、複数行のログエントリに適しています。

$ cat log | sed -n -e '/entry2/,/|!/ p'
LOG|2016-07-26_15:37:45:536|entry2|extra data
on new line|!

ただし、1行の項目には次の項目も表示されるため、悪いことです。

$ cat log | sed -n -e '/entry3/,/|!/ p'
LOG|2016-07-26_15:37:45:536|entry3|!
LOG|2016-07-26_15:37:45:536|entry4|!

sed単一行と複数行のログエントリを処理するために上記の内容を変更する方法についてのアイデアはありますか?

答え1

別のアプローチは、項目が終了するまで一致する行を繰り返すことです。

sed '/entry3|/{:a;/!$/!{n;ba;};p;};d' log

答え2

次の場合は個別に処理する必要があります。

sed -n '/entry3.*[^!]$/, /|!/p; /entry3.*!/p ' log

行がIDと一致する場合そして感嘆符で終わると印刷されます。行がIDと一致する場合そしていいえ感嘆符で終わり、アドレス範囲の先頭を表示します。

関連情報