打印第二个模式匹配的任何行之间的所有行

5

我有一个像这样的电子邮件日志文件:

2013-09-11 12:02:08  INFO: ------------------------------
2013-09-11 12:02:08  INFO: Javamail session sending email
2013-09-11 12:02:08  INFO: Session properties: 
2013-09-11 12:02:08  INFO:    com.hof.email.starttime=20130911120208
2013-09-11 12:02:08  INFO:    mail.smtp.auth=true
2013-09-11 12:02:08  INFO:    mail.smtp.connectiontimeout=60000
2013-09-11 12:02:08  INFO:    mail.smtp.host=mailserver
2013-09-11 12:02:08  INFO:    mail.smtp.port=25
2013-09-11 12:02:08  INFO:    mail.smtp.timeout=60000
2013-09-11 12:02:08  INFO:    mail.transport.protocol=smtp
2013-09-11 12:02:08  INFO: From: Support
2013-09-11 12:02:08  INFO: To: Customer
2013-09-11 12:02:08  INFO: Subject: Your Report Data
2013-09-11 12:02:08  INFO: Message ID: <id>
2013-09-11 12:02:09  INFO: Email sent successfully
2013-09-11 12:02:09  INFO: Javamail session ended
2013-09-11 12:02:09  INFO: ------------------------------

我需要做的是如果电子邮件主题与特定字符串匹配,则打印整条记录。
也就是说,当Subject = 'Your Report Data'时,我想要做的是,在主题匹配中第n-1个出现 '------------------------------' 到第一个出现 '------------------------------' 的所有行都被打印。

3
如果在两条横线之间的部分始终相同,可以使用grep命令,并带有-A-B选项。 - mnagel
主题是否总是块的第12行? - user000001
是的,每个日志条目的结构始终相同。 - Billy
正如@mnagel所指出的那样,如果格式是固定的(----...--行始终与Subject:行相同距离),那么在这种情况下“俗气”的方法是:grep -A 4 -B 12 "INFO:.*Subject: " log.txt - lurker
谢谢 @mnagel,这对我的需求来说完美无缺。 - Billy
4个回答

2

如果两行之间的内容总是相同的,您可以使用带有 -A-Bgrep 命令。


1

这仅适用于 gawk

awk '/Subject: Your Report Data/{printf "%s%s\n",$0,RT}' RS="------------------------------" file

编辑:更复杂的版本,打印正确的部分。
cat file
2013-09-11 12:02:08  INFO: ------------------------------
2013-09-11 12:02:08  INFO: Javamail session sending email
2013-09-11 12:02:08  INFO: Session properties:
2013-09-11 12:02:08  INFO:    com.hof.email.starttime=20130911120208
2013-09-11 12:02:08  INFO:    mail.smtp.auth=true
2013-09-11 12:02:08  INFO:    mail.smtp.connectiontimeout=60000
2013-09-11 12:02:08  INFO:    mail.smtp.host=mailserver
2013-09-11 12:02:08  INFO:    mail.smtp.port=25
2013-09-11 12:02:08  INFO:    mail.smtp.timeout=60000
2013-09-11 12:02:08  INFO:    mail.transport.protocol=smtp
2013-09-11 12:02:08  INFO: From: Support
2013-09-11 12:02:08  INFO: To: Customer
2013-09-11 12:02:08  INFO: Subject: Your Report Data
2013-09-11 12:02:08  INFO: Message ID: <id>
2013-09-11 12:02:09  INFO: Email sent successfully
2013-09-11 12:02:09  INFO: Javamail session ended
2013-09-11 12:02:09  INFO: ------------------------------
2013-09-11 12:02:08  INFO: Javamail session sending email
2013-09-11 12:02:08  INFO: Session properties:
2013-09-11 12:02:08  INFO:    com.hof.email.starttime=20130911120208
2013-09-11 12:02:08  INFO:    mail.smtp.auth=true
2013-09-11 12:02:08  INFO:    mail.smtp.connectiontimeout=60000
2013-09-11 12:02:08  INFO:    mail.smtp.host=mailserver
2013-09-11 12:02:08  INFO:    mail.smtp.port=25
2013-09-11 12:02:08  INFO:    mail.smtp.timeout=60000
2013-09-11 12:02:08  INFO:    mail.transport.protocol=smtp
2013-09-11 12:02:08  INFO: From: Support
2013-09-11 12:02:08  INFO: To: Customer
2013-09-11 12:02:08  INFO: Subject: Error
2013-09-11 12:02:08  INFO: Message ID: <id>
2013-09-11 12:02:09  INFO: Email sent successfully
2013-09-11 12:02:09  INFO: Javamail session ended
2013-09-11 12:02:09  INFO: ------------------------------

awk '/---/ {if (p) {for (j=0;j<i;j++) print a[j]};i=0;p=0;delete a;a[i++]=$0} !/---/ {a[i++]=$0} /Your/ {p=1}'
2013-09-11 12:02:08  INFO: ------------------------------
2013-09-11 12:02:08  INFO: Javamail session sending email
2013-09-11 12:02:08  INFO: Session properties:
2013-09-11 12:02:08  INFO:    com.hof.email.starttime=20130911120208
2013-09-11 12:02:08  INFO:    mail.smtp.auth=true
2013-09-11 12:02:08  INFO:    mail.smtp.connectiontimeout=60000
2013-09-11 12:02:08  INFO:    mail.smtp.host=mailserver
2013-09-11 12:02:08  INFO:    mail.smtp.port=25
2013-09-11 12:02:08  INFO:    mail.smtp.timeout=60000
2013-09-11 12:02:08  INFO:    mail.transport.protocol=smtp
2013-09-11 12:02:08  INFO: From: Support
2013-09-11 12:02:08  INFO: To: Customer
2013-09-11 12:02:08  INFO: Subject: Your Report Data
2013-09-11 12:02:08  INFO: Message ID: <id>
2013-09-11 12:02:09  INFO: Email sent successfully
2013-09-11 12:02:09  INFO: Javamail session ended

1

为了好玩,这里有一个使用GNU grep进行多行搜索解决此问题的方法。关于其工作原理的详细信息,请参阅优秀答案

grep -ozP '(?s)(?<=--\n).*?Subject: Your Report Data.*?(?=\n\N*?--)' 

谢谢您提供的链接和答案。-z是一个应该记住的选项 :) - konsolebox

0

对于不同数量的行,您也可以使用以下 Ruby 代码:

ruby -e 'exp = Regexp.new("^[^\n]+INFO: -{30}$.*?INFO: Subject: #{Regexp.escape(ARGV.shift)}$.*?-{30}$", Regexp::MULTILINE); File.read(ARGV.shift).scan(exp).each{|e| puts e}' "Your Report Data" file

它不会将主题中的字符解释为正则表达式字符。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接