用 sort 和 uniq 统计日志:从排序去重到频次排行
在服务器运维里,日志是最诚实的“黑匣子”:访问量、错误、慢请求都藏在里面。很多人一遇到统计就想写脚本,其实对付大多数“数一数、排一排”的需求,sort 和 uniq 这对老搭档就够了。它们不需要安装、不依赖数据库,一条管道就能出结果。
一、先理解:uniq 只认识“相邻”的重复
uniq 的去重规则常被误解:它只合并相邻的相同行。日志里的 IP、状态码往往是乱序出现的,直接 uniq 几乎去不掉任何东西。所以标准姿势永远是“先排序、再去重”:
sort access.log | uniq
这里 sort 把相同行排到一起,uniq 再把连续的重复行压成一行。记住顺序不能反,这是所有用法的地基。
二、从访问日志里数独立 IP
假设 access.log 每行以客户端 IP 开头,先用 cut 取出第一列,再排序去重、计数:
cut -d ' ' -f 1 access.log | sort | uniq | wc -l
cut -d ' ' 指定空格分隔、取第 1 列;sort 排好序;uniq 去重;wc -l 数行。得到的数字就是独立访客 IP 的个数。想看看到底是哪些 IP,把最后的 wc -l 去掉即可。
三、频次排行:最常访问的 IP 是谁
只知道“有多少个”还不够,经常要知道“谁最多”。uniq -c 会在每行前面加上重复次数,再用 sort -nr 按数字倒序排:
cut -d ' ' -f 1 access.log | sort | uniq -c | sort -nr | head -10
这条命令输出前 10 名最活跃的 IP。sort -nr 的 n 是按数值比较(否则“100”会排在“20”前面),r 是倒序;head -10 只取前十。排查突发流量、发现爬虫时,这就是第一条要跑的命令。
四、统计状态码:看看服务健不健康
Nginx 日志里状态码一般在第 9 列,同样套路:
cut -d ' ' -f 9 access.log | sort | uniq -c | sort -nr
一眼就能看到 200、404、500 各占多少。如果 500 的行数突然抬头,说明后端出问题了;如果 404 集中在某几个路径,往往是旧链接没处理好。
五、按小时看流量高峰
日志时间戳一般在第 4 列,形如 [06/Nov/2026:06:12:00。先用 cut 截取日期和小时部分,再统计:
cut -d ' ' -f 4 access.log | cut -c 2-14 | sort | uniq -c
cut -c 2-14 截掉前面的“[”,保留“06/Nov/2026:06”这样的“日期+小时”。排序计数后,就能看到每小时的请求量,波峰波谷一目了然,扩容、压测时间都好安排。
六、去重后的行还能再加工
sort 和 uniq 的输出本身还是文本,可以继续接管道。比如把结果保存下来留作基线,明天对比:
cut -d ' ' -f 1 access.log | sort | uniq -c | sort -nr > ip_top.txt
今天的数据就是明天的参照物,异常波动一比便知。
七、几个容易踩的坑
第一,忘记先 sort:uniq 不排序等于没去重。第二,数字排序要加 -n,否则是字典序。第三,uniq -c 的计数前面有空格,做二次处理时要注意。第四,大文件先抽样验证:head -1000 access.log | sort | uniq -c,先在小样本上跑通,再上全量。第五,字段位置因日志格式而异,动手前先 head -3 看一眼真实格式,确认列号再写命令。
sort 负责排队,uniq 负责计数,两个小工具串起来,就能完成日志分析里最常见的去重、计数和排行。把这几条命令收进自己的工具箱,下次面对日志,先跑一遍频次排行,再决定要不要上更重的工具——很多时候,答案已经在前十行里了。
- 点赞
- 收藏
- 关注作者
评论(0)