Awk

如何清理日誌文件以僅顯示一次連續重複的行,並用一個數字表示該行重複了多少次?

  • May 8, 2021

目前日誌:

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)”。

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