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

관련 정보