Как показать только следующую строку после совпавшей? - PullRequest
195 голосов
/ 17 сентября 2011
grep -A1 'blah' logfile

Благодаря этой команде для каждой строки, в которой есть «бла», я получаю вывод строки, содержащей «бла», и следующую строку в лог-файле. Это может быть простой, но я не могу найти способ пропустить строку, в которой есть «бла» и только показать следующую строку в выводе.

Ответы [ 10 ]

172 голосов
/ 17 сентября 2011

вы можете попробовать с помощью awk:

awk '/blah/{getline; print}' logfile
136 голосов
/ 17 сентября 2011

, если вы хотите придерживаться grep:

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

или

sed -n '/blah/{n;p;}' logfile
26 голосов
/ 14 января 2013

Трубопровод - ваш друг ...

Используйте grep -A1, чтобы показать следующую строку после матча, затем перенаправьте результат на tail и только захватите 1 строку,

cat logs/info.log | grep "term" -A1 | tail -n 1
13 голосов
/ 15 марта 2013

Отличный ответ от raim, был очень полезен для меня. Это тривиально расширить, чтобы напечатать, например, строка 7 после шаблона

awk -v lines=7 '/blah/ {for(i=lines;i;--i)getline; print $0 }' logfile
5 голосов
/ 24 августа 2015

До сих пор было дано много хороших ответов на этот вопрос, но я все еще скучаю по одному с 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"

Логика всегда состоит в том, чтобы сохранить строку, в которой находится «бла», а затем распечатать те строки, которые идут на одну строку после.

Test

Пример файла:

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

Получить все строки после "бла". Это печатает другой "бла", если он появляется после первого.

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

Получить все строки после "бла", если они не содержат "бла" сами.

$ awk '/blah/ {f=NR} f && NR==f+1' a
1
4
7
5 голосов
/ 14 января 2015

В общем, я согласен, что вы спрашиваете здесь много о grep, и что другой инструмент может быть лучшим решением.Но во встроенной среде я, возможно, не захочу иметь sed или awk просто для этого.Я обнаружил, что работает следующее решение (если они не являются непрерывными совпадениями):

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

По сути, сопоставьте их, добавив 1 строку контекста для каждого совпадения, а затем передайте это через обратное сопоставлениеваш оригинальный шаблон, чтобы раздеть их.Это, конечно, означает, что вы можете предположить, что ваш шаблон не отображается в следующей строке.

5 голосов
/ 17 сентября 2011

Если в следующих строках никогда не содержится «бла», вы можете отфильтровать их с помощью:

grep -A1 blah logfile | grep -v blah

Использование cat logfile | ... не требуется.

5 голосов
/ 17 сентября 2011

Я не знаю ни одного способа сделать это с помощью grep, но можно использовать awk для достижения того же результата:

awk '/blah/ {getline;print}' < logfile
4 голосов
/ 14 ноября 2015

однострочное оповещение perl

просто для удовольствия ... печатать только одну строку после матча

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

еще веселее ... печатать следующеечерез десять строк после матча

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

вроде как обманывает, так как на самом деле есть две команды

3 голосов
/ 17 сентября 2011

Похоже, вы используете не тот инструмент.Grep не так уж и сложен, я думаю, вы хотите использовать awk в качестве инструмента для работы:

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

Если у вас возникнут проблемы, дайте мне знать, я думаю, что этоСтоит немного изучить аук, это отличный инструмент:)

ps Этот пример не выигрывает «бесполезное использование награды кошки»;) http://porkmail.org/era/unix/award.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...