対象は、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"
とすると思う。
awk 文字列の大小比較
こんな感じ
一文字ずつ比較しているみたい