awkを使用した簡単な集計

投稿者: | 2016年3月13日

awkとはUnix上で開発されたプログラミング言語でLinuxやMacに標準で入っています。コマンドラインから使用できアクセスログやエラーログを集計するときに使用されることが多いようです。今回Linuxサーバ内で簡単なログの集計を行うためにawkを使用しました。
まずはテキストを分割します。次のようなログが出力されていたとします。

Feb 26 13:19:24 Server 2016/02/26 13:19:24 INFO  (http-888) [1000030] XXXXXXXXXXXXXXX END s 200 38 /top GET -
Feb 26 13:20:05 Server 2016/02/26 13:20:05 INFO  (http-888) [1000030] XXXXXXXXXXXXXXX END s 200 951 /news GET -
Feb 26 13:25:18 Server 2016/02/26 13:25:18 INFO  (http-888) [1000030] XXXXXXXXXXXXXXX END s 200 55 /top GET -
Feb 26 13:33:41 Server 2016/02/26 13:33:41 INFO  (http-888) [1000030] XXXXXXXXXXXXXXX END s 200 812 /new GET -
Feb 26 13:55:18 Server 2016/02/26 13:55:18 INFO  (http-888) [1000030] XXXXXXXXXXXXXXX END s 200 37 /top GET -
Feb 26 13:55:38 Server 2016/02/26 13:55:38 INFO  (http-888) [1000030] XXXXXXXXXXXXXXX END s 200 216 /other GET -

これについて機能と応答時間を抽出します(先頭から14個目と15個目の項目)。ログのファイル名がaccesslogとします。

$ cat accesslog | awk -F ' ' '{ print $14 $15}'
  38/top
  951/news
  55/top
  812/new
  37/top
  216/other

続いて先ほどのログを機能毎に集計し、応答時間の平均値を求めます。

$ cat accesslog | awk -F ' ' '{ if($0 != "") { a[$15]+=$14; b[$15]+=1 } }END{for(i in a)print i","a[i]/b[i];}'
  /new,812
  /news,951
  /other,216
  /top,43.3333

今回使用したawkコマンドの説明です。awkはテキストを行毎に処理するプログラムです。また、その際に行を分割する機能を持っています。-Fオプションを使用することで分割する文字を指定することができます。
「awk -F ‘ ‘」「awk -F ‘,’」など
次に{}で括った処理を各行に対して行います。例えば「awk {print $1}」と記述すれば分割した項目の1つ目を出力します。また、ifによる条件分岐や変数の定義を行うことも可能です
最後に全ての行を処理した後に後処理を記述することもできます。後処理をENDの後ろに{}で括ることで実装することができます。
上記のことを踏まえた上で応答時間の平均値を求めるコマンドを解説します。

$ awk -F ' ' '{ if($1 != "") { a[$15]+=$14; b[$15]+=1 } }END{for(i in a)print i","a[i]/b[i];}'

①『-F ‘ ‘』
各行をスペース区切りで分割します。
②『{ if($1 != “”) { a[$15]+=$14; b[$15]+=1 } }』
1つ目の項目が空でないなら配列aに14番目の項目を加算、配列bに1を加算します。配列a、bのキーには15番目の項目を指定します。これを各行に対して行います。
③『END{for(i in a)print i”,”a[i]/b[i];}’』
全ての行に対して②の処理を終えた後に
以上、awkを使用した簡単な集計でした。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA