0

I am trying to write a script (well, a one-liner really) to extract the important part of a debug log, so that people can easily send it to me instead of dragging me onto a conference call or having to collect the whole file. I can tell them what to do in less or vi to get the info, but I would like it as a command if possible.

In less:

$ less filename
G
?Server\ version
/SEVERE
[read line including first match for SEVERE from this point, stop reading when get to next instance of SEVERE]

I have been trying to write an awk command that will accomplish this, and it is not going well.

This is as close as I got that does not work:

awk '{if (/Server version/) {chunk=""} else {chunk=chunk $0 RS}} END {printf "%s", chunk}'  filename | awk '/SEVERE/,/SEVERE/'

awk doesn't seem to like using the same pattern for the beginning and end of the part I want printed out at the end.

I am open to using other tools, but for my use case, I need to use utilities that come by default on RHEL7.

If the info helps at all, I am looking at apache tomcat debug logs.

1

If I understand you correctly you want to output the lines between the first and next occurrence of SEVERE after the last occurrence of Server version.

Example input file:

Server version
SEVERE
ignore
SEVERE
Server version
ignore
SEVERE
important
stuff
SEVERE 
ignore
SEVERE
awk '
  /Server version/{ chunk="" }
  /SEVERE/{ logme=(chunk=="") }
  logme{ chunk=chunk $0 RS }
  END{ printf "%s", chunk }
' file

Output:

SEVERE
important
stuff
1
  • Thank you so much! That works perfectly. Now I just have to study it a bit so I understand it. – Paul H Jan 22 at 18:42
1

A multi-line outline: Print line numbers with grep, extract them and use awk

grep -n SEVERE filename | head -n 2 | cut -d ':' -f1

This will output the first 2 line numbers [a, b] containing 'SEVERE' and awk could easily print the SEVERE and intervening lines...

awk 'NR>=a && NR<=b {print $0;}' filename

This could be easily scripted - but it requires a double pass through the log file.

2
  • not sure if I tried to follow this wrong, but I got no output on my example file: $ grep -n SEVERE catalina.2021-01-19-210119205246.log | head -n 2 | cut -d ':' -f1 1 21 and then: $ awk '1>=a && 21<=b {print $0;}' catalina.2021-01-19-210119205246.log no output there. – Paul H Jan 22 at 18:46
  • The second statement should be awk 'NR>=1 && NR<=21 {print $0;}' catalina.2021-01-19-210119205246.log – Jeremy Boden Jan 23 at 20:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.