Bash
如何按日期在日誌文件中儲存唯一 IP 地址的數量?
這個社區的新手。我在 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”之後,使用
sort
and也是如此: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
。為了展示該過程,您可以列印此命令的每個步驟以查看它是如何進行的。