Я анализирую файл почтового ящика, в котором хранятся отчеты сервера электронной почты о неудачно доставленной электронной почте. Я хочу извлечь плохие адреса электронной почты, чтобы удалить их из системы. Файл журнала выглядит так:
...some content...
The mail system
<slavicatomic118@hotmail.com>: host mx1.hotmail.com[65.54.188.94] said: 550
Requested action not taken: mailbox unavailable (in reply to RCPT TO
command)
...some content...
The mail system
<oki88@optimumpro.net>: host viking.optimumpro.net[79.101.51.82] said: 550
Unknown user (in reply to RCPT TO command)
...some content...
The mail system
<sigirna_luka@yahoo.com>: host mta5.am0.yahoodns.net[74.6.140.64] said: 554
delivery error: dd This user doesn't have a yahoo.com account
(sigirna_luka@yahoo.com) [0] - mta1172.mail.sk1.yahoo.com (in reply to end
of DATA command)
...etc.
Адрес электронной почты приходит через 2 строки после строки с «Почтовой системой». Использование grep как это дает мне строку «Почтовая система» и следующие две строки:
grep -A 2 "The mail system" mbox_file
Однако я не знаю, как удалить из этого вывода строку «Почтовая система» и вторую пустую строку. Я думаю, я мог бы написать скрипт PHP / Perl / Python для этого, но мне интересно, возможно ли это с помощью grep или другого стандартного инструмента. Я пытался задать отрицательное смещение для параметра -B:
grep -A 2 -B -2 "The mail system" mbox_file
Но Греп жалуется:
grep: -2: invalid context length argument
Есть ли способ сделать это с помощью grep?
Ответы:
Самый простой способ решить эту проблему, используя
grep
только один канал - это перевернуть еще один перевернутыйgrep
конец. Например:источник
Если вы не привязаны к использованию
grep
, попробуйтеsed
...Когда он находит строку, содержащую «Почтовую систему», он читает следующую строку дважды, через
n;n;
, отбрасывая каждую предыдущую строку, как это происходит.Это оставляет 3-ю строку вашей группы в пространстве шаблона, которая затем печатается с помощью команды sed
p
. Опция-лидер-n
запрещает любую другую печать.Чтобы напечатать следующие две строки, это просто следующий случай и напечатайте еще
n;p
дважды.Чтения следующей строки для нужных вам строк могут быть собраны и напечатаны в виде одного блока всего с одной
p
...N
читает следующую строку и добавляет ее в пространство шаблона,Вот окончательная сокращенная версия ...
Если вам нужен групповой разделитель , подобный тому, который выводит grep wouuld, вы можете использовать команду вставки sed
i
(которая должна быть последней командой в строке) ...Вот синтаксис для включения разделителя группы
Вот вывод для первого совпадения:
источник
-B
для предыдущих строк, поэтому не нужно указывать отрицательное значение.источник
-A 2 -B 2
печатает от двух строк до контекста до 2 строк после контекста. Речь идет о печати от 2 строк после контекста до 4 строк после контекста.Я не вижу смысла в использовании только grep (s), за исключением случаев, когда это строгое ограничение. Это невозможно сделать одним вызовом grep.
источник
Это печатает следующую 1 строку после соответствия регулярному выражению, используя Perl
источник