Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using sed to print range when pattern is inside the range?

I have a log file full of queries, and I only want to see the queries that have an error. The log entries look something like:

path to file executing query
QUERY
SIZE: ...
ROWS: ...
MSG: ...
DURATION: ...

I want to print all of this stuff, but only when MSG: contains something of interest (an error message). All I've got right now is the sed -n '/^path to file/,/^DURATION/' and I have no idea where to go from here.

Note: Queries are often multiline, so using grep's -B sadly doesn't work all the time (this is what I've been doing thus far, just being generous with the -B value)

Somehow I'd like to use only sed, but if I absolutely must use something else like awk I guess that's fine.

Thanks!

like image 739
codekoala Avatar asked Mar 17 '11 15:03

codekoala


2 Answers

You haven't said what an error message looks like, so I'll assume it contains the word "ERROR":

sed -n '/^MSG.*ERROR/{H;g;N;p;};/^DURATION/{s/.*//;h;d;};H' < logname

(I wish there were a tidier way to purge the hold space. Anyone?...)

like image 105
Beta Avatar answered Oct 03 '22 07:10

Beta


I could suggest a solution with grep. That will work if the structure in the log file is always the same as above (i.e. MSG is in the 5th line, and one line follows):

egrep -i '^MSG:.*error' -A 1 -B 4 logfile

That means: If the word error occurs in a MSG line then output the block beginning from 4 lines before MSG till one line after it. Of course you have to adjust the regexp to recognize an error.

This will not work if the structure of those blocks differs.

like image 31
bmk Avatar answered Oct 03 '22 07:10

bmk