Using sed to print range when pattern is inside th

2019-07-19 01:54发布

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!

3条回答
时光不老,我们不散
2楼-- · 2019-07-19 02:24

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

查看更多
淡お忘
3楼-- · 2019-07-19 02:29

Perhaps you can use the cgrep.sed script, as described by Unix Power Tools book

查看更多
趁早两清
4楼-- · 2019-07-19 02:47

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.

查看更多
登录 后发表回答