grep -A1 'blah' logfile

多亏了这个命令,每一行都有'blah',我得到了包含'blah'的行输出和日志文件中的下一行。这可能是一个简单的,但我找不到一种方法来省略一行有'blah',只显示下一行在输出。


当前回答

到目前为止,对于这个问题已经给出了许多很好的答案,但我仍然错过了一个awk没有使用getline的答案。因为,在一般情况下,没有必要使用getline,我将使用:

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"

逻辑始终包括存储找到“blah”的行,然后打印后面一行的行。

Test

示例文件:

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

取“blah”后面的所有行。如果出现在第一个之后,则打印另一个“blah”。

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

获取“blah”之后的所有行,如果这些行本身不包含“blah”。

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

其他回答

如果下一行从来没有包含'blah',你可以过滤他们:

grep -A1 blah logfile | grep -v blah

使用cat logfile |…不需要。

总的来说,我同意您在这里要求使用大量grep,而另一种工具可能是更好的解决方案。但是在嵌入式环境中,我可能不希望使用sed或awk来完成此操作。我发现以下解决方案是有效的(只要它们不是连续的匹配):

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

基本上,匹配它们,为每个匹配附加一行上下文,然后通过原始模式的反向匹配来将它们剥离出来。当然,这意味着您可以假设您的模式不会出现在“下一行”中。

到目前为止,对于这个问题已经给出了许多很好的答案,但我仍然错过了一个awk没有使用getline的答案。因为,在一般情况下,没有必要使用getline,我将使用:

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"

逻辑始终包括存储找到“blah”的行,然后打印后面一行的行。

Test

示例文件:

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

取“blah”后面的所有行。如果出现在第一个之后,则打印另一个“blah”。

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

获取“blah”之后的所有行,如果这些行本身不包含“blah”。

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

reaim的回答很好,对我很有用。将其扩展到打印模式之后的第7行是很简单的

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

Perl一行程序警告

只是为了好玩……匹配后只打印一行

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

更有趣的是……匹配后打印接下来的十行

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

虽然有点作弊,因为实际上有两个命令