直接用awk提取ip并统计访问量前10:awk '{print $1}' access.log | sort | uniq -c | sort -nr | head -10;需确保$1为真实ip,cdn场景改用$http_x_forwarded_for或自定义log_format。

直接用这条命令就能快速拿到访问量前 10 的 IP:
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -10
它适合默认 log_format combined 的日志(IP 在每行第一个字段),执行快、无需额外依赖。
✅ 确保 IP 字段位置正确
Nginx 默认日志格式中,客户端 IP 是第一列,但前提是:
- 没有开启
real_ip_header或set_real_ip_from - 日志没被反向代理(如 CDN)污染(否则
$1可能是代理 IP)
验证方式:
head -1 /var/log/nginx/access.log
看开头是否形如 192.168.1.100 - ...。如果不是,需确认你实际使用的 log_format 中 $remote_addr 对应的字段位置。
⚙️ 更高效写法(单次遍历,不依赖 sort)
避免多次管道排序,用 awk 内置数组计数:
awk '{a[$1]++} END {for (ip in a) print a[ip], ip}' /var/log/nginx/access.log | sort -nr | head -10
-
a[$1]++:以 IP 为键累计次数 -
END块统一输出,减少进程开销 - 后续仍需
sort -nr排序取 Top,但前面省掉了一次sort | uniq
? 常见不准原因和应对
CDN 或代理导致
$1不是真实 IP
→ 改用$http_x_forwarded_for(需确保该头可信)或配置log_format显式记录realip
示例:log_format realip '$http_x_forwarded_for - $remote_user [$time_local] ...';-
日志轮转后路径不对
→ 用zcat处理压缩日志:zcat /var/log/nginx/access.log.1.gz | awk '{print $1}' | sort | uniq -c | sort -nr | head -10 -
IPv6 地址含冒号,被空格截断异常
→ 默认$1对 IPv6 不安全;建议用正则提取:awk '{match($0, /^[0-9a-fA-F:.]+/); print substr($0, RSTART, RLENGTH)}' access.log | ...
? 附:带计数和 IP 对齐的可读输出
awk '{a[$1]++} END {for (ip in a) printf "%-15s %d\n", ip, a[ip]}' /var/log/nginx/access.log | sort -k2 -nr | head -10
会输出类似:
119.90.20.254 21 119.90.20.25 5 119.90.21.2 4
字段对齐,便于扫读。
不复杂但容易忽略细节。











