3

I currently have the output of a log, like the following.

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

I am currently using the following to output lines of a log that contain error and fatal messages, striping the first two columns that contain a timestamp.

awk '/\[[FATAL|ERROR].*] \[.*\]/ { print substr($0, index($0,$3)) }' filename

This produces the exact results I want (at least to summarise count occurrences).

[ERROR  ] [PID] error running program:
[ERROR  ] [PID] some error:
[ERROR  ] [PID] error running program:

Now I want to extend this to include the text for a line that was matched in the above IF the line contains the second pattern.

For example, if the line from the first pattern also contains "error running program" then include the line n lines below. Else print line and keep going.

[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
5
  • 3
    Welcome to the site. I think your awk command contains a flawed regular expression, although it seemingly works because of the limited possibilities for the "severity" tag of your log lines. You use [FATAL|ERROR] to indicate that you want to match either the string FATAL or ERROR in the square brackets. However, [...] defines a character list, so your usage would mean "match any string starting with [, followed by any of F,A,T, |,E,R or O. It works here, but string alternatives should, if at all, be placed in round braces as in (FATAL|ERROR).
    – AdminBee
    Commented Jan 24, 2020 at 8:34
  • To clarify the strings FATAL or ERROR may be found elsewhere in the line. What I'm looking for is the string beginning with [ containing the string FATALor ERROR and ending with ] . But I'll amend the command and verify if still works.
    – nassbar
    Commented Jan 24, 2020 at 9:18
  • The condition of the string FATAL or ERROR being between [ ... ] is already provided for by your specification of \[ before your alternative, so replacing the [ ... ] around the alternative with round braces will not break the correct operation.
    – AdminBee
    Commented Jan 24, 2020 at 9:36
  • Question for clarification: Is the "actual error messages from n lines below" also preceded by the <timestamp> ... [PID] fields on each output line, and do you want to squash all of these output lines into one for the "summary output"?
    – AdminBee
    Commented Jan 24, 2020 at 10:10
  • The lines are not proceeded by <timestamp> ... [PID] the lines themselves are output of a subcommand which contains several lines of meta content, but also the error output of the command executed. I only need the error message itself, which is always a set number of lines below the initial log message.
    – nassbar
    Commented Jan 25, 2020 at 0:30

1 Answer 1

2
$ 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
1
  • 1
    Thanks. Worked like a charm!
    – nassbar
    Commented Jan 25, 2020 at 10:50

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .