awkの連想配列を用いてカウントを取る

はじめに

awk連想配列を覚えると、出来ることの幅が広がる気がしたので、その紹介です。
awkすげーってなったら良いなと思って書きました。

適当なファイルを用意してawkで全量出力する。

コマンド

$ awk '{print $0;}' test.txt 

結果

192.168.0.1 - - [5/Dec/2017:21:00:00 +0000] "GET /index.html HTTP/1.1"
192.168.0.1 - - [5/Dec/2017:21:01:00 +0000] "GET /index.html HTTP/1.1"
192.168.0.1 - - [5/Dec/2017:21:02:00 +0000] "GET /index.html HTTP/1.1"
192.168.0.1 - - [5/Dec/2017:21:00:00 +0000] "GET /index2.html HTTP/1.1"
192.168.0.1 - - [5/Dec/2017:21:01:00 +0000] "GET /index2.html HTTP/1.1"
192.168.0.1 - - [5/Dec/2017:21:02:00 +0000] "GET /index2.html HTTP/1.1"


半角スペース区切りで7列目に存在するリソース毎にカウントを取る。

コマンド

$ awk '{request[$7]++;}END{for(key in request){print key, request[key];}}' test.txt 

結果

/index2.html 3
/index.html 3


半角スペースが連続している場合

(区切り文字無しでパラメータhogeを出力するフォーマットがいけてない。)

$ cat test2.txt 
192.168.0.1 - - [5/Dec/2017:21:00:00 +0000] "GET  /index.html HTTP/1.1"
192.168.0.1 - - [5/Dec/2017:21:01:00 +0000] "GET  /index.html HTTP/1.1"
192.168.0.1 - - [5/Dec/2017:21:02:00 +0000] "GET  /index.html HTTP/1.1"
192.168.0.1 - - [5/Dec/2017:21:00:00 +0000] "GET  /index2.html HTTP/1.1"
192.168.0.1 - - [5/Dec/2017:21:01:00 +0000] "GET hoge /index2.html HTTP/1.1"
192.168.0.1 - - [5/Dec/2017:21:02:00 +0000] "GET  /index2.html HTTP/1.1"
BEGIN{FS="[ ]"}を追加し、連続した半角スペースをそれぞれ区切り文字と認識させる。リソース名は8列目になる。

コマンド

$ awk 'BEGIN{FS="[ ]"}{request[$8]++;}END{for(key in request){print key, request[key];}}' test2.txt 

結果

/index2.html 3
/index.html 3


時間あたりのリクエスト数を取る

このような連想配列を作るイメージ

request[/index.html 21:00]++
request[/index2.html 21:00]++

コマンド

$ awk 'BEGIN{FS="[ ]"}{request[substr($4, 13, 2) ":00 " $8]++;}END{for(key in request){print key, request[key];}}' test2.txt 

結果

21:00 /index2.html 3
21:00 /index.html 3