/var/log/apache2/other_vhosts_access.log
给定一个这样的文件:
example.com:443 1.1.1.1 - - [25/Jan/2021:12:00:00 +0000] "GET /abc/def/ghi?token=jklm12 HTTP/1.1" 200 1000 "-" "Mozilla/5.0 (Macintosh; Intel...
example.com:443 1.1.1.1 - - [25/Jan/2021:12:10:00 +0000] "GET /abc/def/ghi?token=jklm12 HTTP/1.1" 200 1000 "-" "Mozilla/5.0 (Macintosh; Intel...
example.com:443 2.2.2.2 - - [25/Jan/2021:12:20:00 +0000] "GET /abc/def/ghi?token=jklm13 HTTP/1.1" 200 1000 "-" "Mozilla/5.0 (Macintosh; Intel...
...
example.com:443 33.33.33.33 - - [12/Apr/2021:12:00:00 +0000] "GET /abc/def/ghi?token=jklm14 HTTP/1.1" 200 1000 "-" "Mozilla/5.0 (Macintosh; Intel...
example.com:443 4.4.4.4 - - [13/Apr/2021:12:00:00 +0000] "GET /abc/def/ghi?token=jklm12 HTTP/1.1" 200 1000 "-" "Mozilla/5.0 (Macintosh; Intel...
如何获取(或统计)每天不同IP的数量?
例子:
25/Jan/2021
1.1.1.1
2.2.2.2
12/Apr/2021
33.33.33.33
13/Apr/2021
4.4.4.4
或者
25/Jan/2021 2
12/Apr/2021 1
13/Apr/2021 1
如何做到“按天分组”?
答案1
<infile awk -F'[[ :]' '{
dt[$7]=(dt[$7]==""?"":dt[$7]) (!seen[$7,$3]++?"\t" $3:ORS) }
END{ for(d in dt)print d ORS dt[d] }'
(dt[$7]==""?"":dt[$7])
打印数组之前的内容dt如果不为空。
(!seen[$7,$3]++?"\t" $3:ORS)
打印知识产权($3)(带有制表符前缀)如果以前没有看到过DTAE($7),否则打印换行符(默认 ORS)。
dt[$7]= ...
即使用上述结果的值更新每个 DATE($7) 的内容。
25/Jan/2021
1.1.1.1
2.2.2.2
13/Apr/2021
4.4.4.4
12/Apr/2021
33.33.33.33
对输出进行排序(输入数据必须按排序顺序日期,最有可能的日志更频繁地根据日期排序):
<infile awk -F'[[ :]' '{
dt[$7]=(dt[$7]==""?"\0"NR"-" $7 ORS:dt[$7]) (!seen[$7,$3]++?"\t" $3:ORS)
}
END{ for(d in dt) print dt[d] }' |sort -z |cut -z -d'-' -f2-
或者使用 GNU awk 来设置数组的排序选项:
<infile awk -F'[[ :]' '!date[$7]++{ ind++ }
{ dt[ind]=(dt[ind]==""?$7 ORS:dt[ind]) (!seen[$7,$3]++?"\t" $3:ORS)
}
END{ PROCINFO["sorted_in"]="@ind_num_asc"; for(d in dt) print dt[d] }'
25/Jan/2021
1.1.1.1
2.2.2.2
12/Apr/2021
33.33.33.33
13/Apr/2021
4.4.4.4
答案2
接受的答案近乎完美,但总是有不需要的空白行,有时同一行中有多个 IP。
所以这个小小的修改使它对我有用:
awk -F'[[ :]' '{ dt[$7]=(dt[$7]==""?"":dt[$7]) (!seen[$7,$3]++?"\t"$3"\n":"") } END{ PROCINFO["sorted_in"]="@ind_num_asc"; for(d in dt)print d ORS dt[d] }' other_vhosts_access.log
或者如果您想过滤来自特定域/页面的流量
grep "example.com" other_vhosts_access.log |awk -F'[[ :]' '{ dt[$7]=(dt[$7]==""?"":dt[$7]) (!seen[$7,$3]++?"\t"$3"\n":"") } END{ PROCINFO["sorted_in"]="@ind_num_asc"; for(d in dt)print d ORS dt[d] }'