How to show only next line after the matched one?

2019-01-08 04:05发布

问题:

grep -A1 'blah' logfile

Thanks to this command for every line that has 'blah' in it, I get the output of the line that contains 'blah' and the next line that follows in the logfile. It might be a simple one but I can't find a way to omit the line that has 'blah' and only show next line in the output.

回答1:

you can try with awk:

awk '/blah/{getline; print}' logfile


回答2:

if you want to stick to grep:

grep -A1 'blah' logfile|grep -v "blah"

or

sed -n '/blah/{n;p;}' logfile


回答3:

Piping is your friend...

Use grep -A1 to show the next line after a match, then pipe the result to tail and only grab 1 line,

cat logs/info.log | grep "term" -A1 | tail -n 1


回答4:

Great answer from raim, was very useful for me. It is trivial to extend this to print e.g. line 7 after the pattern

awk -v lines=7 '/blah/ {for(i=lines;i;--i)getline; print $0 }' logfile


回答5:

In general, I agree you're asking a lot of grep here, and that another tool may be the better solution. But in an embedded environment, I may not want to have sed or awk just to do this. I found the following solution works (as long as they're not contiguous matches):

grep -A1 AT\+CSQ wvdial.out | grep -v AT\+CSQ

Basically, match them, appending 1 line of context for each match, and then pipe that through an inverse match of your original pattern to strip those out. This of course means you can assume that your pattern doesn't show up in the "next" line.



回答6:

Many good answers have been given to this question so far, but I still miss one with awk not using getline. Since, in general, it is not necessary to use getline, I would go for:

awk ' f && NR==f+1; /blah/ {f=NR}' file  #all matches after "blah"

or

awk '/blah/ {f=NR} f && NR==f+1' file   #matches after "blah" not being also "blah"

The logic always consists in storing the line where "blah" is found and then printing those lines that are one line after.

Test

Sample file:

$ cat a
0
blah1
1
2
3
blah2
4
5
6
blah3
blah4
7

Get all the lines after "blah". This prints another "blah" if it appears after the first one.

$ awk 'f&&NR==f+1; /blah/ {f=NR}' a
1
4
blah4
7

Get all the lines after "blah" if they do not contain "blah" themselves.

$ awk '/blah/ {f=NR} f && NR==f+1' a
1
4
7


回答7:

I don't know of any way to do this with grep, but it is possible to use awk to achieve the same result:

awk '/blah/ {getline;print}' < logfile


回答8:

If that next lines never contain 'blah', you can filter them with:

grep -A1 blah logfile | grep -v blah

The use of cat logfile | ... is not needed.



回答9:

It looks like you're using the wrong tool there. Grep isn't that sophisticated, I think you want to step up to awk as the tool for the job:

awk '/blah/ { getline; print $0 }' logfile

If you get any problems let me know, I think its well worth learning a bit of awk, its a great tool :)

p.s. This example doesn't win a 'useless use of cat award' ;) http://porkmail.org/era/unix/award.html



回答10:

perl one-liner alert

just for fun... print only one line after match

perl -lne '$next=($.+1)if/match/;$.==$next&&print' data.txt

even more fun... print the next ten lines after match

perl -lne 'push@nexts,(($.+1)..($.+10))if/match/;$.~~@nexts&&print' data.txt

kinda cheating though since there's actually two commands



标签: awk sed grep