【问题标题】:grep for timestamp and wordgrep 时间戳和单词
【发布时间】:2014-08-07 23:04:36
【问题描述】:

所以我试图通过一个日志文件计数行,其中包含过去 30 分钟内的时间戳和一个单词。 我有用于查找时间戳的工作代码:

grep "^$(date -d -30minute +'%Y-%m-%d %H')" /path/to/the/derp | wc -l

一个示例日志文件可以是:

2014-08-07 00:00:03.001 000 GoogleGeoCodeService blah blah blah
2014-08-07 00:00:01.001 000 carrier check java.net.SocketTimeoutException

如果两个条目都发生在最后半小时内,我如何计算第二行而不是第一行?我试过只添加另一个管道,但我从来没有得到正确的结果:

grep "^$(date -d -30minute +'%Y-%m-%d %H')" /path/to/the/derp | wc -l | grep -i "exception"

【问题讨论】:

  • date 技巧仅在当前分钟数大于 30 时才有效。
  • @choroba Huh 我在实践中没有注意到这一点,但谢谢。您对其他方法有什么建议吗?
  • 我可能会使用 Perl。
  • 要获取第二行,请在再次调用grep 之前删除| wc -l,然后重试。您正在使用wc -l 将输出减少到一个数字。
  • @DavidC.Rankin 好的有道理。我应该做两个 greps 然后减少到一个数字?我想要符合时间戳并包含“异常”而不是行本身的行数。我只是想获得一些比赛。

标签: bash grep


【解决方案1】:

您的代码的主要问题是,您正在 greping 获取正好 30 分钟前的日期戳,而不是过去 30 分钟内的任何时间。

您可以通过将当前 shell 的日期(以秒为单位)作为变量传递来使用 Awk 完成您想要的操作。然后您可以将日志中的日期戳转换为以秒为单位的日期,然后从当前日期变量中减去它,以查看它是否在最近 30 分钟(1800 秒)内。

awk -v current=$(date +%s) -v IGNORECASE=1 -F\. 'BEGIN {
    n=0
}
/^[0-9]{1,4}-[0-9]{1,2}-[0-9]{1,2} [0-9]{2}:[0-9]{2}:[0-9]{2}./ && /exception/ {
    time=$1
    format="\\1 \\2 \\3 \\4 \\5 \\6"
    seconds=mktime(gensub(/(....)-(..)-(..) (..):(..):(..)/, format, "", time))
    if((current - seconds) <= 1800)
        n++
}END{
    print n
}' /path/to/the/derp

【讨论】:

    【解决方案2】:

    继续你所拥有的,只需将wc 移到最后:

    grep "^$(date -d -30minute +'%Y-%m-%d %H')" /path/to/the/derp |
      grep -i "exception" |
      wc -l
    

    但实际上这可以简化:

    grep -ic "^$(date -d -30minute +'%Y-%m-%d %H').*exception" /path/to/the/derp
    

    虽然 awk 解决方案似乎是解决日期问题的好方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-02-09
      • 2020-09-26
      • 1970-01-01
      • 1970-01-01
      • 2014-04-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多