03/03/2014 12:31:21 BLOCK 10.1.34.1 11:22:33:44:55:66
03/03/2014 12:31:22 ALLOW 10.1.34.2 AA:BB:CC:DD:EE:FF
03/03/2014 12:31:25 BLOCK 10.1.34.1 55:66:77:88:99:AA
私はawkを使用して、1つのコマンドで上記の「ブロック」と「アクセス」の出現回数をカウントしようとしています。
最初にWordの「ブロック」を試しましたが、カウンターが機能していないようです。私のコードが間違っている場所を誰でも見ることができますか?
awk ' BEGIN {count=0;} { if ($3 == "BLOCK") count+=1} end {print $count}' firewall.log
配列を使用する
awk '{count[$3]++} END {for (Word in count) print Word, count[Word]}' file
具体的に「ブロック」したい場合:END {print count["BLOCK"]}
これは非コードソリューションです。ステップをパイプ( "|")でつなげることができます。
awk '{print $3}' file | sort | uniq -c
awk '{print $ 3}'
3列目を印刷します。awkのデフォルトのレコード区切り文字は空白です。
ソート
結果を並べ替える
uniq -c
繰り返し発生回数を数える
コードが機能しない理由はEND
が大文字と小文字を区別するためです。スクリプトは変数end
が存在するかどうかをチェックし(存在しない)、最後のブロックは実行されません。それを変更すれば、それは機能するはずです。
また、すべての変数が0でインスタンス化されるため、BEGIN
ブロックは必要ありません。
以下に、代わりに使用したい別の方法を追加しました。
これはglennに似ていますが、必要な単語のみをキャプチャします。そのため、メモリをほとんど使用しないはずです。
Gawkの使用(一致の3番目の引数用)
awk 'match($3,/BLOCK|ALLOW/,b){a[b[0]]++}END{for(i in a)print i ,a[i]}' file
このブロックは、BLOCK
またはALLOW
が3番目のフィールドに含まれている場合にのみ実行されます。
一致は、配列bに一致したものをキャプチャします。
次に、一致したフィールドの配列aがインクリメントされます。
END
ブロックでは、キャプチャされた各フィールドに発生回数が出力されます。
出力は
ALLOW 1
BLOCK 2
あなたの声明をテストしました
awk ' BEGIN {count=0;} { if ($3 == "BLOCK") count+=1} end {print $count}' firewall.log
2つの変更を行うことでBLOCK
を正常にカウントできました
end
は大文字にする必要があります$
from print $count
したがって、次のようになります。
awk ' BEGIN {count=0;} { if ($3 == "BLOCK") count+=1} END {print count}' firewall.log
動作する簡単なステートメントは次のとおりです。
awk '($3 == "BLOCK") {count++ } END { print count }' firewall.log
awk
呼び出しのエラーは、「END」ブロックにprint $count
。それはcount
変数の内容を受け取り、それが整数であると仮定し、入力の最後の行で対応するフィールドを見つけようとします。本当に欲しいのはprint count
は、count
変数の値を出力するだけです。 bash
、awk
、python
などの間で異なる変数参照スキームを混同するのは簡単な場合があるため、間違いを犯すのは簡単です。