
我正在使用以下格式的日誌檔案:
Oct 12 01:28:26 server program: 192.168.1.105 text for 1.105
Oct 12 01:30:00 server program: 192.168.1.104 text for 1.104
Oct 12 01:30:23 server program: 192.168.1.103 text for 1.103
Oct 12 01:32:39 server program: 192.168.1.101 text for 1.101
Oct 12 02:28:26 server program: 192.168.1.105 text for 1.105
Oct 12 02:30:00 server program: 192.168.1.104 text for 1.104
Oct 12 02:30:23 server program: 192.168.1.103 text for 1.103
Oct 12 02:32:39 server program: 192.168.1.101 text for 1.101
我需要實現這個目標:
Oct 12 02:28:26 server program: 192.168.1.105 text for 1.105
Oct 12 02:30:00 server program: 192.168.1.104 text for 1.104
Oct 12 02:30:23 server program: 192.168.1.103 text for 1.103
Oct 12 02:32:39 server program: 192.168.1.101 text for 1.101
如何將新輸出傳送到文件?我已經嘗試過這個:
awk '!_[$6]++ {a=$6} END{print a}' logfile
但它沒有給我預期的結果。如何使用 awk 或 sed 只給我上次看到字串匹配的唯一行或基於日期/時間?
答案1
如果您打算進行第二遍(您很可能必須這樣做),您也可以只儲存行號而不是完整記錄。它使邏輯更容易。
awk 'NR == FNR {if (z[$6]) y[z[$6]]; z[$6] = FNR; next} !(FNR in y)' logfile logfile
正確性證明:
在處理每一行結束時,到目前為止處理的每個行號都是任何一個中的一個值z
,或者中的索引(不是值)y
,但不能同時存在。
z
在每次迭代結束時,由 中 的值表示的行準確且僅是迄今為止為每個 IP 位址看到的最新記錄。
因此,的索引y
正是我們希望的線不是列印.
答案2
保存整行(用作$6
數組索引)並END
迭代數組的元素:
awk '{z[$6]=$0};END{for (i in z) print z[i]}' logfile
但結果不會被排序...你可以這樣做:
awk '{z[$6]=NR" "$0};END{for (i in z) print z[i]}' logfile | sort -k1,1n | cut -f2-
### this space ^ is a literal TAB
這保存了行號。加上行內容即可依行號排序。
其他方法涉及第二遍以按日期排序(因為這是日誌),但如果輸入包含重複行(即整行),則會列印重複條目 - 例如grep
:
awk '{z[$6]=$0};END{for (var in z) print z[var]}' logfile | grep -Fxf- logfile
或僅與awk
:
awk 'NR==FNR{z[$6]=$0;next}
FNR==1{for (var in z) y[z[var]]}
$0 in y' logfile logfile
答案3
如果您只有同一天的線路,您可以像這樣處理:
sort -k6 -k3r logfile | uniq -f3 | sort -k3
如果您排隊的時間超過一天,您仍然可以使用這種基本方法,但您的排序必須變得更加巧妙。上面的命令只能處理一天的記錄,因為它使用時間戳的時間部分(例如02:28:26
)作為整個時間戳的代理。
答案4
透過按行反轉文件,邏輯變得更簡單
$ tac logfile | awk '!seen[$6]++' | tac
Oct 12 02:28:26 server program: 192.168.1.105 text for 1.105
Oct 12 02:30:00 server program: 192.168.1.104 text for 1.104
Oct 12 02:30:23 server program: 192.168.1.103 text for 1.103
Oct 12 02:32:39 server program: 192.168.1.101 text for 1.101