用 awk 快速处理表格型日志:按列筛、求和与去重

举报
yd_28502004 发表于 2026/11/02 06:19:35 2026/11/02
【摘要】 服务器上的日志大多是表格型的:一行一条记录,字段之间用空格或逗号隔开,比如访问日志里的 IP、时间、状态码,或者 df 输出里的挂载点和使用率。遇到这种数据,awk 是最顺手的工具:它按行读、按列拆,不用写脚本就能做筛选、统计和去重。 1. 先看清列:默认按空白分列awk 默认把连续的空格和制表符当成分隔符,第 1 列是 $1,第 2 列是 $2,整行是 $0。比如想从访问日志里只看 IP ...

服务器上的日志大多是表格型的:一行一条记录,字段之间用空格或逗号隔开,比如访问日志里的 IP、时间、状态码,或者 df 输出里的挂载点和使用率。遇到这种数据,awk 是最顺手的工具:它按行读、按列拆,不用写脚本就能做筛选、统计和去重。

1. 先看清列:默认按空白分列

awk 默认把连续的空格和制表符当成分隔符,第 1 列是 $1,第 2 列是 $2,整行是 $0。比如想从访问日志里只看 IP 和状态码:awk '{print $1, $9}' access.log。如果字段之间是逗号,比如 CSV,要先告诉它分隔符:awk -F',' '{print $1, $3}' data.csv,-F 后面就是分隔符。

动手前先用 head -5 文件名 看几行样例,确认每列到底是什么、分隔符是空格还是逗号,列数对不对。这一步花不了半分钟,却能避免后面统计结果全错。

2. 按条件筛:只留关心的行

awk 的模式写在花括号前面,满足条件的行才会执行后面的动作。想找状态码是 500 的请求:awk '$9 == 500' access.log,$9 是状态码那一列。想找某个 IP 的记录:awk '$1 == "192.168.1.10"' access.log,字符串条件要加引号。

条件可以组合:awk '$9 >= 500 && $9 < 600' access.log 找出所有 5xx 的行。先筛再统计,结果会干净很多,排查时不用在一堆无关记录里翻。

3. 求和与计数:不用导进表格也能算

awk 可以在处理每一行时累加,最后统一输出。比如统计每个状态码各出现几次:awk '{count[$9]++} END {for (c in count) print c, count[c]}' access.log,count 是按状态码分组的计数器,END 表示所有行读完后再执行。

求和同理:假设第 4 列是响应字节数,算总流量就是 awk '{sum += $4} END {print sum}' access.log。数据量不大时,这比把日志导进表格软件再求和快得多,而且结果直接落在终端里,方便接着用管道处理。

4. 去重:先排序再去重,或者用 awk 一步到位

去重最稳的组合是 sort | uniq,但 awk 也能一步做:awk '!seen[$1]++' access.log 只保留每个 IP 第一次出现的行,后面重复的直接跳过。seen 是个关联数组,记录每个值出现过几次,!seen[$1]++ 的意思是“这个值还没见过时才打印”。

要注意:awk 去重保留的是第一次出现的顺序,不排序。如果既要去重又要按次数排序,先用 awk 计数,再把结果管道给 sort -nr,按次数从大到小排,排在前面的就是最值得先看的。

5. 两个常见坑

一是列数不固定:有的行缺字段,后面的列会整体前移,统计就错位了。先用 awk '{print NF}' 文件 | sort | uniq -c 看看每行的列数是不是一致,NF 就是当前行的列数。二是分隔符里有空格:比如时间字段本身带空格,列就会被多切一刀,这时要么用 -F 指定更准确的分隔符,要么先用 sed 把时间字段处理一下再交给 awk。

记住一个顺序就够了:先看样例定列,再筛条件缩小范围,最后做统计或去重。awk 本身不改原文件,只负责读和算,查完再决定要不要动手修,操作就安全多了。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。