Apache 日志:每天使用 sed 或 awk 有多少个不同的 IP?

Apache 日志:每天使用 sed 或 awk 有多少个不同的 IP?

/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] }'

相关内容