如何按日期在日志文件中存储唯一 IP 地址的数量?

如何按日期在日志文件中存储唯一 IP 地址的数量?

新加入这个社区。我在 bash 脚本中执行此操作。我的问题几乎概括了我正在寻找的内容。我有一个日志文件,其中包含一堆 IP 地址和其他数据。我想计算每个特定日期的唯一 IP 地址的数量并将其存储到变量中。关于如何使用 grep 和 awk 来做到这一点有什么想法吗?

日期格式为 11/Feb/2020(这是一个示例)。

日志文件中的示例文本:

57.34.156.99 - - [11/Feb/2020:04:32:18 +0330]
43.21.223.33 - - [11/Feb/2020:09:13:05 +0330]
87.44.212.82 - - [14/Mar/2020:06:22:01 +0330]
43.21.223.33 - - [11/Feb/2020:11:05:32 +0330]

上述输出:

11/Feb/2020:2
14/Mar/2020:1

如您所见,我只想对重复的 IP 地址进行一次计数。

任何帮助表示赞赏。如果我应该提供更多信息,请告诉我。

答案1

这是问题示例格式的答案,但一般来说,其他日志格式的过程类似(通常日期是 ISO 格式并且在第一个字段中)。要将任务与格式分开,首先仅查看 IP 和日期:

> awk '{print substr($4,2,10), $1}' file
11/Feb/202 57.34.156.99
11/Feb/202 43.21.223.33
14/Mar/202 87.44.212.82
11/Feb/202 43.21.223.33

我们可以使用一个关联数组,其中哈希值将是日期和 ip,并且它会随着“date-ip”的出现而增加。另一个数组用于计算实际结果,其中哈希将仅是日期。

awk '{d = substr($4,2,10)} !seen[d FS $1]++ {cnt[d]++}
    END {for (x in cnt) print x ":" cnt[x]}
    ' file | sort -t ":" -rnk2

输出:

11/Feb/202:2
14/Mar/202:1
  • cnt请注意,数组的顺序未定义,因此通过 ip 计数通过END管道传输日期很有用。sort或者你可以使用GNU awk 数组排序函数

  • 中的变量awk不是隐式定义的,最初为零或空字符串,因此对于任何新的“date-ip”集,!seen[date-ip]++都将为 true,之后它会增加。所以下次我们遇到这个“date-ip”时,它会是假的,我们不会增加cnt[date]


在每行仅提取“date-ip”之后,使用sortand进行相同的操作:uniq

> awk '{print substr($4,2,10), $1}' file | sort -u | awk '{print $1}' | uniq -c
      2 11/Feb/202
      1 14/Mar/202

在这里,我们在排序时删除重复项sort -u(因为稍后uniq需要对其输入进行排序),仅保留第一个字段(日期),最后uniq -c打印每个唯一日期的计数。这对于不太熟悉的人来说更具可读性awk。为了演示该过程,您可以打印该命令的每个步骤以查看其进展情况。

相关内容