Bash

如何按日期在日誌文件中儲存唯一 IP 地址的數量?

  • May 9, 2022

這個社區的新手。我在 bash 腳本中執行此操作。我的問題幾乎總結了我在尋找什麼。我有一個日誌文件,其中包含一堆 IP 地址以及其他數據。我想計算每個特定日期的唯一 IP 地址數量並將其儲存到變數中。關於如何使用 grep 和 awk 做到這一點的任何想法?

日期格式為 2020 年 2 月 11 日(這是一個範例)。

日誌文件中的範例文本:

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 地址。

任何幫助表示讚賞。如果我應該提供更多資訊,請告訴我。

這是問題範例格式的答案,但一般來說,其他日誌格式的過程類似(通常日期是 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]++它將為真,之後它會增加。所以下次我們遇到這個“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。為了展示該過程,您可以列印此命令的每個步驟以查看它是如何進行的。

引用自:https://unix.stackexchange.com/questions/616378