【问题标题】:Print all lines between pattern where any line matches second pattern打印模式之间的所有行,其中任何行与第二个模式匹配
【发布时间】:2013-09-17 07:39:16
【问题描述】:

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

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 次出现的 '------------------------------' 和第一次出现的 '------------------------------' 之间的所有行.

【问题讨论】:

  • 如果行与行之间的部分始终相同,您可以使用grep-A-B
  • 主题总是块的第 12 行吗?
  • 是的,每个条目的日志条目结构始终相同。
  • 正如@mnagel 所指出的,如果格式是固定的(----...-- 行与Subject: 行的距离始终相同),那么“俗气”的做法是: grep -A 4 -B 12 "INFO:.*Subject: " log.txt 在这种情况下。
  • 谢谢你,@mnagel,这对我来说很好用。

标签: regex bash sed awk


【解决方案1】:

如果行之间的部分始终相同,您可以将grep-A-B 一起使用。

【讨论】:

    【解决方案2】:

    这仅适用于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
    

    【讨论】:

      【解决方案3】:

      对于不同数量的行,您也可以使用此 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
      

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

      【讨论】:

        【解决方案4】:

        为了好玩,这里有一个 GNU grep 方法可以通过多行搜索来解决这个问题。有关此great answer 工作原理的详细信息

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

        【讨论】:

        • +1 感谢您提供链接和此答案。 -z 是一个应该记住的选项:)
        猜你喜欢
        • 2013-02-23
        • 1970-01-01
        • 2015-04-14
        • 2015-05-07
        • 1970-01-01
        • 2019-04-29
        • 2019-01-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多