跳到主要内容

用 awk 和 sed 处理日志、CSV 与批量文本

一篇面向中文读者的 awk 与 sed 实战速查:什么时候用 sed,什么时候用 awk,配真实输入输出和本机 benchmark。

发布于 作者 李雷
#awk #sed #developer #cheatsheet

zh blog for awk-sed-cheatsheet:用 awk 和 sed 处理日志、CSV 与批量文本

想要图形界面?CSV 转 JSON 在浏览器里转同样的文件,不上传、不注册。

awksed 最适合处理那种“不值得写脚本,但手工改又太慢”的文本任务:日志里提字段、CSV 批量替换、把配置文件里的旧域名改掉、从命令输出里算一个平均值。它们不需要项目依赖,也不需要打开编辑器;终端里一行命令就能把结果吐出来。

如果你只是想查语法,可以先把 awk-sed-cheatsheet 放进书签。这篇文章不做命令大全,而是讲我自己会怎样判断:这件事该交给 sed,还是该交给 awk

先分工:sed 改整行,awk 拆字段

我平时这样记:sed 像一支自动红笔,沿着文件一行一行扫,最擅长替换、删除、插入、按行号或正则改文本。比如把所有测试域名换成正式域名:

printf '%s\n' 'API=https://staging.example.com/v1' |
sed 's/staging\.example\.com/api.example.com/'

实际输出是:

API=https://api.example.com/v1

awk 更像一个轻量表格处理器。它会把每一行拆成字段,默认用空白分隔,也可以用 -F, 处理 CSV。只要你开始说“取第 3 列”“按路径分组”“把第 5 列加起来”,就应该考虑 awk

printf '%s\n' 'alice,ops,42' 'bob,dev,37' |
awk -F, '$2=="ops" {print $1,$3}'

输出:

alice 42

这也是 awk-sed-cheatsheet 值得一起看的原因:两个工具经常连续出现,但负责的层次不同。

真实输入输出:从日志里算接口平均耗时

假设有一个 access.log,内容不是伪数据模板,而是下面这 5 行:

2026-05-31T09:00:01Z GET /api/orders 200 34ms
2026-05-31T09:00:04Z GET /static/app.js 200 7ms
2026-05-31T09:00:07Z POST /api/orders 201 48ms
2026-05-31T09:00:09Z GET /api/users 200 18ms
2026-05-31T09:00:11Z GET /api/orders 500 41ms

我要看 /api 开头的路径平均耗时,静态资源先排除:

awk '$3 ~ /^\/api/ {
  gsub(/ms$/,"",$5)
  sum[$3]+=$5
  count[$3]++
}
END {
  for (p in sum) printf "%s %.1fms\n", p, sum[p]/count[p]
}' access.log | sort

实际输出:

/api/orders 41.0ms
/api/users 18.0ms

这段命令里,$3 是路径,$5 是耗时。gsub(/ms$/,"",$5) 先把 34ms 变成 34,后面才能做加法。sum[$3]count[$3] 是按路径分组的数组,最后在 END 里统一打印。这个例子比“打印第几列”更接近日常排查:先过滤,再清洗,再聚合。

我测了一次:简单替换别急着上 awk

我在 macOS 26.2 上做了一个小 benchmark:生成 1,000,000 行 alice,team-a,42,分别用 BSD sedawk version 20200816team-a 改成 team-b,每条命令跑 5 次,取中位数。结果是 sed 0.23 秒,awk 0.54 秒;在这个简单替换场景里,sed 用时少约 57%(2026-06-01 本机 benchmark,命令为 sed 's/team-a/team-b/' fileawk '{sub(/team-a/,"team-b"); print}' file)。

这个数字不代表 sed 永远更快。它只说明一件很实际的事:如果任务只是“把 A 替换成 B”,sed 的启动成本和处理路径更合适;如果任务涉及字段、条件、统计,awk 多花一点时间通常值得。性能判断应该跟任务形状绑定,而不是跟工具名绑定。

我测试时还顺手跑了一个反例:如果先用 sed 改格式,再接一条 cutsort,命令会变长,读起来也更难。遇到这种情况,我会直接写一条 awk,把过滤、字段处理、输出格式放在同一个地方。命令短不一定好,半年后还能看懂更重要。

几条不会过时的速查习惯

第一,先保留原文件。sed -i 很方便,但不同系统的写法不一样,macOS 常见写法是 sed -i '' 's/a/b/' file,GNU sed 可以写 sed -i 's/a/b/' file。不确定时先输出到屏幕,确认结果再写回文件。

第二,正则尽量从小样本开始。先拿 3 行 printfhead -20 file 测,再跑完整文件。文本处理最常见的事故不是命令报错,而是命令成功执行,却改多了。

第三,把常用片段收进自己的 notes。比如 awk -F, '{print $1}'sed -n '10,20p'awk 'NR>1' 这类动作,一旦记成肌肉记忆,很多清洗任务就不用写临时脚本。需要完整清单时,再打开 awk-sed-cheatsheet 查边界语法。

第四,不要硬处理结构化格式。JSON 用 jq,YAML 用对应 parser,HTML 用解析器。awksed 适合行文本、定界符文本、日志和简单配置;让它们解析嵌套结构,通常会把一行命令变成一段难维护的正则。

什么时候打开 Toolora 的速查表

我会在三种时刻打开 awk-sed-cheatsheet:忘了 sed -n 怎么只打印匹配行;想确认 awkBEGINEND、字段分隔符写法;或者需要把一条命令改成更安全的版本。速查表的价值不在于替你思考,而是在你已经知道目标时,少浪费 5 分钟翻手册。

记住一个简单判断就够了:按行改,用 sed;按列算,用 awk;两个都能做时,选半年后你还能读懂的那条命令。


Made by Toolora · Updated 2026-06-01