一、替换:最常见的用法
sed 's/old/new/' file # 每行只替换第一个
sed 's/old/new/g' file # 每行替换所有
sed 's/old/new/2' file # 只替换第 2 个
sed -n 's/old/new/p' file # 只输出发生替换的行
s 后面三个斜杠的顺序是 s/模式/替换/标志。标志 g 是全局,p 是打印,i 是忽略大小写(GNU 扩展)。
分隔符可以换,处理含斜杠的路径时很有用:
sed 's|/usr/local/bin|/opt/bin|g' file
二、原地修改:-i 的跨平台差异
# GNU sed(Linux)
sed -i 's/old/new/g' file
sed -i.bak 's/old/new/g' file # 同时留备份
# BSD sed(macOS)必须给后缀参数,空字符串也要给
sed -i '' 's/old/new/g' file
sed -i '.bak' 's/old/new/g' file
在 macOS 上直接写 sed -i 's/a/b/' file,会把 s/a/b/ 当成备份后缀,然后不修改原文件,还可能生成奇怪名字的文件。跨平台脚本里建议统一用 -i.bak,兼容两边。
三、删除与打印
sed '5d' file # 删除第 5 行
sed '2,10d' file # 删除 2–10 行
sed '/^$/d' file # 删除空行
sed '/^#/d' file # 删除注释行
sed '/pattern/d' file # 删除匹配行
sed -n '1,5p' file # 只打印前 5 行(类似 head)
sed -n '/start/,/end/p' file # 打印两个标记之间的内容
最后一条在提取配置文件某个段落时特别好用。
四、分组引用
# 把 2026-11-03 改成 2026/11/03
sed -E 's/([0-9]{4})-([0-9]{2})-([0-9]{2})/\1\/\2\/\3/' file
() 分组,\1 \2 引用。注意 -E(BSD 是 -E,GNU 也可用 -r)才支持不转义的 () 和 {},基础正则里要写成 \(...\)。
五、多命令与脚本
sed -e 's/a/b/' -e 's/c/d/' file # 多个表达式
sed 's/a/b/; s/c/d/' file # 分号分隔
sed -f rules.sed file # 从文件读规则
六、误操作怎么补救
- 先预览再改:
sed 's/old/new/g' file | diff file -看清楚再-i。 - 永远带备份:
-i.bak,出问题mv file.bak file回滚。 - 批量前先小样本:
ls *.conf | head -3 | xargs sed -i.bak 's/old/new/g'。 - 重要文件用 git:改完
git diff一眼看出改了什么,比备份更可控。
七、常见坑
- 特殊字符要转义:替换内容里有
/&\时需要处理,&在替换串里代表「整个匹配」。 - 贪婪与跨行:sed 按行处理,默认无法跨行匹配;跨行要用
NPD或改用 perl/awk。 - 中文:
sed按字节处理,一般没问题,但涉及.匹配单字符时可能切到半个汉字。 - 空文件:
sed -i对空文件正常,但如果命令写错(比如少了引号),可能把文件清空。
小结
s/old/new/g 是核心;-i 在 macOS 必须带后缀参数;删除用 d、打印用 -n p;分组用 () 和 \1;批量修改前先 diff 预览并留 .bak。