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