事情本身不复杂,线索都在日志里。站点 IPv6 蜘蛛请求占三成,用 awk 默认空格分隔统计,$1 只拿到地址前半段,按 IP 去重后数量翻倍,报表和 GSC 差了三成。

第一反应是「用 cut 按单空格切分,地址被拆成多列」,验证下来不成立。

真正麻烦的地方在于,几个原因的现象几乎一样。IPv6 地址本身不含空格,但日志字段用多空格对齐。少数情况下是awk 默认 FS 会合并连续空格,字段位置随 UA 里的空格漂移。

少数情况下是log_format 没有固定,字段顺序在版本升级后变过。

动手时先看一行原始日志的字段分布

awk 'NR==1{for(i=1;i<=NF;i++) print i, $i}' access.log

然后用正则按固定格式提取 IP 和 URI

awk 'match($0,/^([0-9a-f:.]+) .* "(GET|HEAD) ([^ ]+)/,m){print m[1],m[3]}' access.log | head

接着改用 JSON 日志避免字段漂移

log_format json escape=json '{"ip":"$remote_addr","uri":"$request_uri","status":$status}';

末了按前缀粗分网段核对数量

awk '{print substr($1,1,10)}' access.log | sort | uniq -c | sort -rn | head

怎么算真的好了,看的是同一批现象。去重后的蜘蛛 IP 数与 GSC 的抓取主机数落在同一量级,IPv6 和 IPv4 请求不再被拆成两条。

统计脚本要先把字段顺序固定住,日志格式一改,所有按列取值的脚本都会失效。拖得越久,排查成本越高,因为现场状态会被后续操作覆盖。

作者 9823189