【问题标题】:awk filter lines from log by timeawk 按时间过滤日志中的行
【发布时间】:2016-07-06 16:39:11
【问题描述】:

我的日志结构如下:

2016-07-06 06:53:35,764 INFO   com.myown.filter.BaseLoggingFilter log 777 * Server responded with a response on thread ajp-bio-8009-exec-1
777 < 501
777 < Content-Type: application/json

2016-07-06 07:00:00,820 INFO   com.myown.filter.BaseLoggingFilter log 778 * Server has received a request on thread ajp-bio-8009-exec-2
778 > GET https://webservice/endpoint
778 > accept: */*
778 > Accept-Encoding: gzip,deflate
778 > authorization: ***[MASKED]***
778 > connection: Keep-Alive
778 > content-length: 0
778 > host: webservice
778 > user-agent: Apache-HttpClient/4.3.6 (java 1.5)

我正在寻找一种按时间过滤这些条目的方法。假设我想在早上 7 点之前获得所有条目。

我设法写了以下内容:

cat webservice.log | awk '$2~/([01]?[0-9]|2[0-3]:[0-5][0-9]:[0-5][0-9])/ && $2 < "07:00:00"'

这只会打印出包含日期和时间的行。

2016-07-06 06:53:35,764 INFO   ...

现在我还想包含与请求对应的其他行。

我尝试过使用变量,但我无法完全弄清楚。我通过谷歌搜索将以下代码片段拼凑在一起,但它不起作用。

cat webservice.log | awk '$2~/([01]?[0-9]|2[0-3]:[0-5][0-9]:[0-5][0-9])/ && $2 > "00:00:00" {p=1}
$2~/([01]?[0-9]|2[0-3]:[0-5][0-9]:[0-5][0-9])/ && $2 < "07:00:00" {p=0}
p {print $0}'

我希望这段代码做什么:

所以,当第二个字段是时间,并且大于 00:00:00 时,p=1 并且该行将被打印。如果以下行没有找到日期,它们也只是打印出来(因为 p 仍然是 1)。如果在第二个字段是时间的地方出现了一行,但它大于 07:00:00,则 p 将变为 0,并且这些行将停止打印。

但这不起作用。我对 AWK 工作原理的理解可能有问题。

谢谢!

【问题讨论】:

  • 假设匹配行之后的 #of 行是常量,您可以使用 egrep 和类似 ` 0[0-6]:[0-9]{2}:[0-9]{2} 的模式, . So final command could look like egrep -A5 ' 0[0-6]:[0-9]{2}:[0-9]{2}, ' webservice.log` 其中 5 表示要打印的行数和 'A'表示“比赛之后”
  • 是的,这就是问题所在。行数不是恒定的(就像我的例子一样)。
  • 我不明白你的问题是什么。与其问问题,不如说它似乎是一个答案。尽管被描述为有效,但它实际上是否有效?如果是这样,你应该这么说,什么是错的。
  • 嗨,MAP,我无法实现我想要实现的目标。最后一段代码实际上不起作用。我已编辑问题以更好地反映这一点。

标签: awk


【解决方案1】:

我看到您的日志条目以空行分隔。我们可以使用它来将一个条目与下一个条目分开:

$ awk -F'[ :]+' '$2<7' RS="" logfile
2016-07-06 06:53:35,764 INFO   com.myown.filter.BaseLoggingFilter log 777 * Server responded with a response on thread ajp-bio-8009-exec-1
777 < 501
777 < Content-Type: application/json

工作原理

  • -F'[ :]+'

    这会将字段分隔符设置为任意数量的空格或冒号。使用此设置,第一个字段是日期,第二个字段是小时,第三个是分钟,等等。

  • $2&lt;7

    这将打印小时字段 $2 小于 7 的任何记录。

  • RS=""

    这告诉 awk 读取一个以空行分隔的段落作为一个记录。因此,一次打印会导致整个条目(记录)被打印出来,而不仅仅是它的第一行。

【讨论】:

    猜你喜欢
    • 2014-07-22
    • 1970-01-01
    • 2013-01-08
    • 1970-01-01
    • 1970-01-01
    • 2013-10-20
    • 1970-01-01
    • 2016-03-22
    • 1970-01-01
    相关资源
    最近更新 更多