我正在解析一个邮箱文件,该文件存储未成功发送的电子邮件的电子邮件服务器报告。我希望提取不良电子邮件地址,以便将它们从系统中删除。日志文件如下所示:
...some content...
The mail system
<[email protected]>: 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
<[email protected]>: host viking.optimumpro.net[79.101.51.82] said: 550
Unknown user (in reply to RCPT TO command)
...some content...
The mail system
<[email protected]>: host mta5.am0.yahoodns.net[74.6.140.64] said: 554
delivery error: dd This user doesn't have a yahoo.com account
([email protected]) [0] - mta1172.mail.sk1.yahoo.com (in reply to end
of DATA command)
...etc.
电子邮件地址位于“邮件系统”一行之后的两行。像这样使用 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 抱怨道:
grep: -2: invalid context length argument
有没有办法用 grep 来做到这一点?
答案1
解决这个问题的最简单方法grep
是grep
在最后再倒一个管道。例如:
grep -A 4 "The mail system" temp.txt | grep -v "The mail system" | grep -v '^\d*$'
答案2
如果您没有被锁定使用grep
,请尝试sed
...
sed -n '/The mail system/{n;n;p}'
当它找到包含“邮件系统”的行时,它会通过 读取下一行两次,n;n;
同时丢弃前面的每一行。
这会将您的组的第三行留在模式空间中,然后通过 sed 打印p
命令打印该行。前导-n
选项阻止所有其他打印。
要打印接下来的两行,这只是一个例子下一步并打印 n;p
又两次。
sed -n '/The mail system/{n; n;p; n;p; n;p}'
您需要的行的下一行读取可以累积并打印在一个块中,只需一个p
... N
读取下一行并将其附加到模式空间,
这是最终的精简版本......
sed -n '/The mail system/{n;n;N;N;p}'
如果你想要一个组分隔符,类似于 grep 输出的内容,您可以使用 sed 的插入命令i
(必须是一行中的最后一个命令)...
这是包含一个的语法组分隔符
sed -n '/The mail system/{n;n;N;N;p;i--
}' > output-file # or | ...
这是第一场比赛的输出:
<[email protected]>: host mx1.hotmail.com[65.54.188.94] said: 550
Requested action not taken: mailbox unavailable (in reply to RCPT TO
command)
--
答案3
grep -A 2 -B -2 "The mail system" mbox_file
-B
用于前面的行,因此不需要给出负值。
grep -A 2 -B 2 "The mail system" mbox_file # This will work please check
答案4
如果你想删除前两行,请将其通过管道传输到sed
sed '1,2d'
如
grep -A 2 "The mail system" mbox_file | sed '1,2d'