【问题标题】:regex | List of result from grep正则表达式 | grep 的结果列表
【发布时间】:2021-10-07 22:06:10
【问题描述】:

以下 grep 命令为我提供了从 7 月 1 日到 7 月 31 日上午 8 点到下午 4 点之间的请求数。

zgrep -E "[01\-31]/Jul/2021:[08\-16]" localhost_access.log* | wc -l

我不想收到当月的所有请求,而是每天的请求。我当然可以输入命令 31 次,但这很乏味。有没有办法将每天的请求显示在另一个下方,以便我得到以下结果(理想情况下按数字排序),例如

543

432

321

等等

怎么做?

【问题讨论】:

  • 您的正则表达式实际上不起作用 - 请参阅 What is the difference between square brackets and parentheses in a regex?
  • 第一个无关紧要,第二个范围是(0[8-9])|(1[0-6])
  • @bryan 您的正则表达式错误,它读取文件 31 次(而不是一次)。
  • @Bohemian 唯一的答案是错误的,但已被接受,我们无法添加其他答案。完全清楚作者想要什么,因此不需要任何调试。结束这个问题根本没有帮助:-(

标签: regex linux awk grep


【解决方案1】:

您想根据一行中的某个值计算行数。这对 awk 来说是个好工作。使用 grep-only,您总是必须每天处理一次输入文件。无论如何,我们需要先修复您的正则表达式:

zgrep -E "[01\-31]/Jul/2021:[08\-16]" localhost_access.log* | wc -l

[08\-16] 匹配字符 08-16。你要匹配的是(0[89])|(1[0-6]);即0,后跟89 - 或- 1 之一,后跟0-6 范围之一。为方便起见,我们假设日期中为正常日期,因此将日期与[0-9]{2}(两位数)匹配。

这是您的任务的完整 awk:

awk -F/ '/[0-9]{2}\/Jul\/2021:(0[89])|(1[0-6])/{a[$1]++}END{for (i in a) print "day " i ": " a[i]}' localhost_access.log*

解释:

  • /[0-9]{2}\/Jul\/2021:(0[89])|(1[0-6])/ 匹配 7 月每天(08-16)的日期和时间
  • {a[$1]++} 构建一个包含 key=day 和出现次数计数器的数组。
  • END{for (i in a) print "day " i ": " a[i]} 在处理完所有输入文件后打印数组

由于我们已将字段分隔符设置为 /,因此您需要更改 a[$1] 以解决正确的位置(实际日期前多两个斜杠:a[$3])。 (当然这可以通过更动态的方式来解决。)

例子:

$ cat localhost_access.log
01/Jul/2021:08 log message
01/Jul/2021:08 log message
02/Jul/2021:08 log message
02/Jul/2021:07 log message
$ awk -F/ '/[0-9]{2}\/Jul\/2021:(0[89])|(1[0-6])/{a[$1]++}END{for (i in a) print "day " i ": " a[i]}' localhost_access.log*
day 01: 2
day 02: 1

运行 zcat | awk 以防您的日志文件被压缩,但请记住上面的正则表达式仅搜索“Jul/2021”。

【讨论】:

  • 感谢这个解决方案和非常详细的描述!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-04
  • 2013-05-01
  • 2014-06-29
  • 2018-04-16
  • 1970-01-01
相关资源
最近更新 更多