現在、以下のログ出力があります。
20200124_075926.795633 [24_1859] [ERROR ] [PID] error running program:
...
...
actual error message from n lines below
...
20200124_075929.261693 [24_1859] [INFO ] [PID] blah
20200124_075929.374937 [24_1859] [PERF ] [PID] blah blah
20200124_075930.660998 [24_1859] [ERROR ] [PID] some error:
20200124_075956.793528 [24_1859] [ERROR ] [PID] error running program:
...
...
actual error message from n lines below
...
私は現在、エラーと致命的なメッセージを含むログ行を出力し、タイムスタンプを含む最初の2つの列を削除するために次のように使用しています。
awk '/\[[FATAL|ERROR].*] \[.*\]/ { print substr($0, index($0,$3)) }' filename
これにより、私が望む正確な結果が生成されます(少なくとも発生回数の合計)。
[ERROR ] [PID] error running program:
[ERROR ] [PID] some error:
[ERROR ] [PID] error running program:
それでは、上記のIFで一致する行のテキストを含めるように拡張したいと思います。この行には2番目のパターンが含まれています。
たとえば、最初のパターンの行に " error running program
"も含まれている場合は、次のn行が含まれます。それ以外の場合は、行を印刷して続行します。
[ERROR ] [PID] error running program: actual error message from n lines below
[ERROR ] [PID] some error:
[ERROR ] [PID] error running program: actual error message from n lines below
答え1
$ cat tst.awk
{
sub(/\r$/,"")
txt = substr($0, index($0,$3))
}
/\[(FATAL|ERROR)[^]]*] \[.*]/ {
if ( /error running program:/ ) {
pfx = txt OFS
cnt = 4
}
else {
cnt = 1
}
}
cnt && !--cnt { print pfx txt; pfx="" }
$ awk -f tst.awk file
[ERROR ] [PID] error running program: message from n lines below
[ERROR ] [PID] some error:
[ERROR ] [PID] error running program: message from n lines below