awk で Apache のアクセスログを時間範囲指定で検索

estis2019/02/09 (土) 23:56 に投稿

対象は、Apache のアクセスログ。

ログフォーマットは、
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %D"


127.0.0.1 - - [10/Feb/2019:00:00:14 +0900] 127.0.0.1:80 "GET /server-status?auto HTTP/1.1" 200 1325 "-" "munin/2.0.43 (libwww-perl/6.05)" 1081

 

時間は、第4列に
 [10/Feb/2019:00:00:14
のように、記述されている。

 

時間の指定は、hh:mm:ss 形式で、
09:10:11
のように指定したい。

第4列を最初の:(年の後の:)で二つの列に分けて、第4列後半部分と比較したい。

sed -e 's/:/ /' access_log
して
127.0.0.1 - - [10/Feb/2019:00:00:14 +0900] 127.0.0.1:80 "GET /server-status?auto HTTP/1.1" 200 1325 "-" "munin/2.0.43 (libwww-perl/6.05)" 1081

127.0.0.1 - - [10/Feb/2019 00:00:14 +0900] 127.0.0.1:80 "GET /server-status?auto HTTP/1.1" 200 1325 "-" "munin/2.0.43 (libwww-perl/6.05)" 1081
にする。

 

その後で、
awk '$5 >= "00:00:00" && $5 <= "00:10:00"'
のようにして検索する。

awk '"00:00:00" <= $5 && $5 <= "00:10:00"'
でも同じこと。

 

だがこのままでは、
[10/Feb/2019 00:00:14 +0900]
のように、年の後が : ではなく スペース なので、
sed -e 's/\(\[[^\/]*\/[^\/]*\/[^ ]*\)//'
で、
[10/Feb/2019 00:00:14 +0900]
に戻す。

全部まとめるとこんな感じ。

$ sed -e 's/:/ /' access_log | awk '"00:00:00" <= $5 && $5 <= "00:00:30"' |sed -e 's/\(\[[^\/]*\/[^\/]*\/[^ ]*\) /\1:/'
127.0.0.1 - - [10/Feb/2019:00:00:02 +0900] 127.0.0.1:80 "GET /server-status?auto HTTP/1.1" 200 1323 "-" "munin/2.0.43 (libwww-perl/6.05)" 1314
127.0.0.1 - - [10/Feb/2019:00:00:07 +0900] 127.0.0.1:80 "GET /server-status?auto HTTP/1.1" 200 1323 "-" "munin/2.0.43 (libwww-perl/6.05)" 448
127.0.0.1 - - [10/Feb/2019:00:00:14 +0900] 127.0.0.1:80 "GET /server-status?auto HTTP/1.1" 200 1325 "-" "munin/2.0.43 (libwww-perl/6.05)" 1081

しかし、最後のsed の正規表現を覚えるのがメンドーくさい。

 

awk で、split($4, time, ":") しておいて、
time[2] と時
time[3] と分
time[4] と秒
を別々に比較するか、

chktime=time[2]":"time[3]":"time[4]
しておいて
"00:00:00" <= chktime && chktime <= "00:10:00"
とすると思う。

Comments

Comment

こんな感じ

$ echo 'ああ
あいう
あか
あかい
あき ' | awk '$1 >= "あい" && $1 <= "あか"'
あいう
あか

一文字ずつ比較しているみたい