行内で1回繰り返される行のみを表示し、その行が何回繰り返されたかを示す数字を表示するようにログファイルを整理するにはどうすればよいですか?

行内で1回繰り返される行のみを表示し、その行が何回繰り返されたかを示す数字を表示するようにログファイルを整理するにはどうすればよいですか?

現在のログ:

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について学びました。誰かが私を解決策につなげるか、これを楽しい練習として見ることができることを願っています。乾杯。

答え1

必要ありません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

答え2

行の先頭の数に満足している場合は、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デフォルト正規表現(BRE)の代わりに拡張正規表現(オプション)、つまりEREを使用します。

  • 各行から先行スペースを削除します。
  • 各行の先頭にあるすべての数字を括弧で囲み、行の終わりに移動します。
  • 各行の末尾に「(1)」がある場合は削除します。

答え3

使用 アッユーティリティ 次のように、一意のイベント数を導出できます。

$ awk '
{t=substr($0,1+index($0,FS))}
prev != t {
  if (NR>1) {fx(line,knt)}
  knt = 0
  prev = t
}{
  line = $0
  knt++
}
END {fx(line,knt)}
function fx(a,b) {
  print a (b>1?sprintf("%s(%d)",OFS,b):"")
}
' file
18:56:54 Info: Starting
18:56:57 Error: timed out (3)
18:56:58 Info: reconnected
18:56:59 Error: timed out

メモ:-

  • 先行スペース/連続スペースがないとします。

答え4

注文する

uniq -f 1 -c filename| awk '{print $2,$3,$4,$5,$1}'| awk '{if($NF > 1){$NF="("$NF")";print }else{$NF="";print }}'

出力

18:56:54 Info: Starting 
18:56:55 Error: timed out (3)
18:56:58 Info: reconnected 
18:56:59 Error: timed out 

関連情報