awk 打印模式匹配的行,如果模式 1 的行有模式 2,则打印模式 1 的行和后面的第 n 行作为单行

awk 打印模式匹配的行,如果模式 1 的行有模式 2,则打印模式 1 的行和后面的第 n 行作为单行

我目前有日志的输出,如下所示。

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
...

我当前正在使用以下内容输出包含错误和致命消息的日志行,并条带包含时间戳的前两列。

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 中匹配的行的文本,该行包含第二个模式。

例如,如果第一个模式中的行也包含“ 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

相关内容