Awk
如何清理日誌文件以僅顯示一次連續重複的行,並用一個數字表示該行重複了多少次?
目前日誌:
18:56:54 Info: Starting 18:56:55 Error: timed out 18:56:56 Error: timed out 18:56:57 Error: timed out 18:56:58 Info: reconnected 18:56:59 Error: timed out
期望的輸出:
18:56:54 Info: Starting 18:56:55 Error: timed out (3) 18:56:57 Info: reconnected 18:56:58 Error: timed out
我的日誌文件可以有數千個重複行,我想使用 bash/linux 命令複製 chrome 日誌的行為。
我發現這個很接近: 刪除部分重複的連續行,但保留第一個和最後一個
它給出了這個神奇的 awk 命令:
awk '{n=$2$3$4$5$6$7}l1!=n{if(p)print l0; print; p=0}l1==n{p=1}{l0=$0; l1=n}END{print}' file
(至關重要的是,排除 n=$1 允許時間戳不同,這是必需的。為壓縮行顯示的確切時間戳並不重要。)
但是我還需要添加一個計數器,所以我清楚地知道消除了什麼,在可讀性和準確性之間做出了適當的折衷(唯一失去的資訊將是重複消息的確切時間,擁有第一個或最後一個時間戳就足夠了。 )
謝謝,我不擅長 awk,剛剛了解了 uniq,希望有人可以將我連結到解決方案,或者將其視為一個有趣的練習。乾杯。
不需要
awk
,直接使用uniq
,uniq -c -f 1 file
該
-c
選項給出在輸入中連續找到一行的次數,您可以使用 跳過第一個空格或製表符分隔欄位中的時間戳-f 1
。給出問題中數據的範例:
$ uniq -c -f 1 file 1 18:56:54 Info: Starting 3 18:56:55 Error: timed out 1 18:56:58 Info: reconnected 1 18:56:59 Error: timed out
如果您對行首的計數感到滿意,
uniq
那麼您只需要:$ uniq -f 1 -c log.txt 1 18:56:54 Info: Starting 3 18:56:55 Error: timed out 1 18:56:58 Info: reconnected 1 18:56:59 Error: timed outhet
-f 1
跳過第一個欄位,-c
計算行數。要獲得您要求的確切格式,您需要處理
uniq
的輸出,例如sed
:$ uniq -f1 -c log.txt | sed -E -e 's/^[[:space:]]+//; s/^([[:digit:]]+)[[:space:]]+(.*)/\2 (\1)/; s/ \(1\)$//' 18:56:54 Info: Starting 18:56:55 Error: timed out (3) 18:56:58 Info: reconnected 18:56:59 Error: timed out
sed 腳本使用擴展正則表達式(
-E
選項),即 ERE,而不是預設的基本正則表達式 (BRE),並且:
- 從每一行去除前導空格
- 將每行開頭的所有數字移動到行尾,用括號括起來
- 如果存在,則從每行的末尾刪除“ (1)”。