sed 与 awk 实战对比:什么时候该用哪个
搜”命令行批量替换文本”,答案里有的用 sed,有的用 awk,看着好像都能解决问题,但不知道自己该学哪个、什么场景该用哪个。两者确实经常一起出现在同一批搜索结果里——但它们解决的其实是不同维度的问题:sed 面向”行”做替换、删除、插入;awk 面向”列”做结构化处理。搞清楚这个区别,选工具就不用再猜了。
这是 Linux 命令系列的一篇,承接 Linux 常见命令与工具地图。
sed 基本用法:按行处理文本
sed(stream editor,流编辑器)默认逐行读取输入,对每一行执行指定的编辑命令后输出结果,不提供交互式编辑界面——写脚本自动化批量处理文本,正是它的设计目的。最核心的命令是 s,替换文本:
1 | sed 's/old/new/' file.txt |
默认情况下 sed 不会修改原文件,只是把处理结果打印到标准输出。想直接改文件本身,要加 -i(in-place)——这里有个必须提前知道的跨平台坑:
1 | # macOS / BSD sed |
同一条 sed -i 命令,在 macOS 上能跑通,搬到 Linux 服务器上可能报错(或者反过来)——写跨平台脚本时这是最容易被忽略的细节。
除了替换,sed 还能按行号删除或者操作某个范围:
1 | sed '2d' file.txt |
sed 常用参数速查表
| 参数/命令 | 作用 |
|---|---|
s/old/new/ |
替换命令,只替换每行第一个匹配 |
s/old/new/g |
加 g,替换每行所有匹配 |
-i |
原地修改文件;macOS/BSD 必须带空字符串参数 -i '',GNU/Linux 直接 -i 即可 |
Nd |
删除第 N 行,如 2d |
N,Md |
删除第 N 到第 M 行 |
-e |
一次执行多个表达式,不用重复调用 sed |
awk 基本用法:按列处理结构化文本
awk 是一门以”按行扫描、按字段处理”为核心的小型编程语言,处理思路跟 sed 不一样——它默认把每一行按空白字符拆成若干”字段”,用 $1、$2 这些变量取某一列:
1 | echo "alice 25 engineer" | awk '{print $1}' |
几个内置变量,日常最常用:
1 | awk '{print NF}' file.txt |
按条件过滤是 awk 真正擅长的场景:
1 | awk '$3 > 100 {print $1}' data.txt |
awk 常用参数与内置变量速查表
| 参数/变量 | 作用 |
|---|---|
$0 |
整行原始内容 |
$1、$2… |
第 1、第 2……个字段 |
NF |
当前行的字段总数(Number of Fields) |
NR |
累计处理到第几行,跨文件累计(Number of Records) |
FNR |
当前文件内的行号,跨文件会重新计数 |
-F |
指定字段分隔符,默认是空白字符 |
BEGIN {...} |
处理任何一行之前执行一次,常用来初始化 |
END {...} |
处理完所有行之后执行一次,常用来输出汇总 |
同一个任务,两种工具的差距在哪
假设有一份访问日志,每行是”路径 响应时间(ms)”,想找出响应时间超过 500ms 的所有路径。用 awk 几乎是原生支持:
1 | awk '$2 > 500 {print $1}' access.log |
用 sed 做同样的事,会很别扭——sed 的正则匹配本质是”文本模式匹配”,不理解”这一列的值是不是大于 500”这种数值比较,得先把数值范围拆成一堆正则模式去匹配文本形式,写出来又长又脆弱,稍微换一种数字格式就得重新调整正则。这不是 sed 的缺陷,是它压根不是为这类场景设计的——sed 面对的是”文本”,awk 面对的是”字段和数值”。
该用哪个:判断标准
- 只是替换、删除、插入某几行文本,不涉及”按列取值”或者”数值比较”——用
sed,更直接 - 需要”取第几列””按某一列的值筛选””跨行做统计汇总”——用
awk,这是它的设计初衷 - 两者也能组合使用,比如先用
awk提取出需要的列,再用sed调整输出格式,但没必要为了”只用一个工具”硬凑一个别扭的写法
写到这里
sed 和 awk 都是几十年历史的经典 Unix 工具,功能远不止本文列的这些(sed 支持完整的模式空间和保持空间操作,awk 本身就是一门小型编程语言,支持自定义函数、数组),但日常排查和批处理,本文这些用法已经能覆盖大部分场景。选错工具通常不是因为哪个”更强”,而是没看清任务本质是”处理行”还是”处理列”。










