Как получить 2 или 3 строки, одна из которых содержит текст, который я хочу, а другие чуть ниже?

33

Это снимок журнала ошибок:

06:16:29,933 ERROR EmailRMManager$:45 - Exception In get Message
com.rabbitmq.client.AlreadyClosedException: clean connection shutdown; reason: Attempt to use closed channel
    at com.rabbitmq.client.impl.AMQChannel.ensureIsOpen(AMQChannel.java:195)
    at com.rabbitmq.client.impl.AMQChannel.rpc(AMQChannel.java:222)
    at com.rabbitmq.client.impl.AMQChannel.rpc(AMQChannel.java:208)
    at com.rabbitmq.client.impl.AMQChannel.exnWrappingRpc(AMQChannel.java:139)
    at com.rabbitmq.client.impl.ChannelN.basicGet(ChannelN.java:645)

Я делаю следующую команду:

cat foo.log | grep ERROR чтобы получить ОП как:

06:16:29,933 ERROR EmailRMManager$:45 - Exception In get Message

Какую команду я должен выполнить, чтобы получить вывод как

06:16:29,933 ERROR EmailRMManager$:45 - Exception In get Message
    com.rabbitmq.client.AlreadyClosedException: clean connection shutdown; reason: Attempt to use closed channel

т. е. также отображать строки после шаблона?

theTuxRacer
источник
Является ли com.rabbitmq.clientтекст на следующей строке начинается с begginning или имеют некоторые пробелы перед ним?
Евгений Коньков

Ответы:

62

Просто сделайте:

grep -A1 ERROR

Команда -A1grep указывает, что после матча должна быть указана 1 строка. -Bвключает строки перед матчем, если вам это тоже нужно.

Джереми Керр
источник
о, это тоже было бы полезно.
theTuxRacer
12
И -Cвключает в себя строки как до, так и после матча («С» означает «контекст», я считаю).
Мариус Гедминас
5

Для более портативного способа есть awk

awk '/ERROR/{n=NR+1} n>=NR' foo.log

Или, может быть, вы хотите, чтобы все строки с отступами следовали?

awk '/^[^[:blank:]]/{p=0} /ERROR/{p=1} p' foo.log
geirha
источник
2
: О, это хорошая информация, но, скорее, перебор! тем не менее, полезно знать другой метод :)
theTuxRacer
Хотелось бы мне понять, как awkработают эти команды.
Firefeather
3
@Firefeather awk.freeshell.org - хороший ресурс для изучения awk. Справочная страница по GNU awk тоже довольно хороша.
гейра
1

Я нашел это решение:

cat apache.error.log | grep -Pzo '^.*?Exception In get Message.*?\ncom\.rabbitmq.*?(\n(?=\s).*?)*$'

Где (\n(?=\s).*?)*означает:

  • \n найти следующую строку
  • (?=\s) где начинается с пробела
  • .*? до конца строки
  • (...)* Найти такие строки несколько раз

PS. Вы можете изменить этот шаблон, \ncom\.rabbitmq.*?если вторая строка начинается с пробела\s

Евгений Коньков
источник