![ログファイル内のエラーメッセージをカウントする](https://rvso.com/image/192214/%E3%83%AD%E3%82%B0%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E5%86%85%E3%81%AE%E3%82%A8%E3%83%A9%E3%83%BC%E3%83%A1%E3%83%83%E3%82%BB%E3%83%BC%E3%82%B8%E3%82%92%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88%E3%81%99%E3%82%8B.png)
com.mysql.jdbc.MysqlDataTruncation: Data truncation: Out of range value for column 'current_state' at r:1
com.mysql.jdbc.MysqlDataTruncation: Data truncation: Out of range value for column 'current_state' at r:2
com.mysql.jdbc.MysqlDataTruncation: Data truncation: Out of range value for column 'current_state' at r:5
java.lang.NullPointerException:12
java.lang.NullPointerException:7
java.lang.NullPointerException:18
java.lang.NullPointerException:2
ご覧のとおり、重複した MySQL エラーが 3 つあり、その頻度が最後に表示されます。最初のエラーでは 1、2 番目のエラーでは 2、3 番目では 5 と表示されます。スクリプトを合計とともに 1 つの重複行のままにしておきたいです。Java エラーについても同じことを行います。
期待される出力:
com.mysql.jdbc.MysqlDataTruncation: Data truncation: Out of range value for column 'current_state' at r:8
java.lang.NullPointerException:39
答え1
awk 'BEGIN{ FS=OFS=":" }
{ freq=$NF; sub(/:[^:]*$/, ""); seen[$0]+=freq }
END{ for (x in seen) print x, seen[x] }' infile
FS は入力フィールド区切り文字で、OFS は出力フィールド区切り文字です。両方ともコロンに設定し、最後のフィールドを$NF
一時変数に取得しfreq
て、sub() 関数を使用して現在の入力レコードから最後のフィールドを削除します$0
。
こうすることで、seen[$0]+=freq
最後のフィールドの値について、変数に以前保持していた頻度と同じログ行 (最後のフィールドはすでに除外されています) を合計しますfreq
。
そして最後に、配列をループし、行とその合計頻度を出力します。