grep -A1:如何只显示匹配后的下一行

grep -A1 'blah' logfile 

由于这条命令对每一行都有'blah'的命令,我得到了包含'blah'的行的输出以及日志文件中后面的下一行。 这可能是一个简单的,但我不能find一种方法来省略“blah”,只显示在输出中的下一行的行。

你可以试试awk:

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

如果你想坚持grep:

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

要么

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

pipe道是你的朋友…

使用grep -A1显示下一行,然后将结果传送到tail ,只抓取1行,

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

来自raim的好回答,对我来说非常有用。 把这个扩展到打印模式之后的第7行是微不足道的

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

看起来你在那里使用了错误的工具。 Grep不是那么复杂,我想你应该加强awk作为工作的工具:

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

如果你有任何问题,让我知道,我认为它值得学习一点awk,它是一个伟大的工具:)

ps这个例子没有赢得“无用的猫奖”;) http://porkmail.org/era/unix/award.html

我不知道有什么办法可以用grep来做到这一点,但是可以使用awk来达到同样的结果:

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

如果下一行不包含“blah”,则可以使用grep -A1 blah logfile | grep -v blah过滤 grep -A1 blah logfile | grep -v blah使用“cat logfile | …”是不需要的。

总的来说,我同意你在这里问了很多grep,而另一个工具可能是更好的解决scheme。 但是在embedded式环境中,我可能不想要sedawk来做这件事。 我发现以下解决scheme可行(只要它们不是连续的匹配):

 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" 

要么

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

逻辑总是包含存储find“blah”的行,然后打印那些行之后的行。

testing

示例文件:

 $ 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 

perl单线警报

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

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

更有趣…赛后打印下十条线

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

有点欺骗,因为实际上有两个命令