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开发者_JS百科 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!
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?...)
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.
Perhaps you can use the cgrep.sed script, as described by Unix Power Tools book
精彩评论