sed 命令速查表 - Linux 文本编辑常用命令大全
sed 的核心只有两块:s/// 负责替换,行地址负责圈定作用范围,两者组合才能表达「只改某些行里的某段文本」。表按替换、删除、插入与追加、打印、正则、多行操作六组铺开,对应六类真实需求:批量改配置值、删空行或注释、在指定行前后插入、只输出匹配行做检查、写出符合预期的正则、摊平跨行结构。要防的是改错不可逆——sed -i 直接改原文件且没有确认环节,所以先不带 -i 跑一遍看输出,确认后再用 -i.bak 留备份。正则一组的坑在方言:BSD 与 GNU sed 默认都是 BRE,+、?、| 必须转义或用 -E 切到 ERE;GNU sed 支持替换串里的换行而 BSD 不支持,多行处理只能用 N 与 P、D 组合。分工是:改内容用 sed,改结构用 awk。跨平台差异:macOS 的 sed -i 必须跟备份后缀,Linux 可直接 -i。
典型使用场景
面向需要批量改写配置文件的开发者。sed 的风险点集中在「不可逆」:`-i` 原地编辑没有撤销,且分隔符 `/` 与模式里的路径常撞车。本表按替换、删除、插入追加、打印、正则、多行操作六组组织。其中三条建议最实用:改前用 `-i.bak` 留备份、模式里含 `/` 时改用 `|` 作分隔符、以及任何替换先不带 `-i` 预览一遍再落盘。
替换 Substitute 8
sed 's/old/new/' filesed 's/old/new/g' filesed 's/old/new/2' filesed 's/old/new/I' filesed -i 's/old/new/g' filesed -i.bak 's/old/new/g' filesed 's/\/path\/old/path\/new/g' filesed 's|old|new|g' file删除 Delete 7
sed '5d' filesed '5,10d' filesed '/pattern/d' filesed '/^$/d' filesed '/^#/d' filesed '$d' filesed '1d;$d' file插入与追加 Insert & Append 5
sed '5i\new text' filesed '5a\new text' filesed '/pattern/i\new text' filesed '/pattern/a\new text' filesed '5i\line1\nline2' file打印 Print 5
sed -n '5p' filesed -n '5,10p' filesed -n '/pattern/p' filesed -n '1p;$p' filesed 's/old/new/p' file正则表达式 Regular Expression 7
sed 's/^prefix/new/' filesed 's/suffix$/new/' filesed 's/\<word\>/new/g' filesed 's/[0-9]/X/g' filesed 's/[^0-9]/X/g' filesed 's/\(pattern\)/\1/g' filesed -E 's/(old)/\1-new/g' file多行操作 Multi-line 5
sed ':a;N;$!ba;s/\n//g' filesed 'N;s/\n/ /' filesed '/start/,/end/s/old/new/g' filesed '/start/,/end/d' filesed '/start/,/end/p' file参数矩阵
| 参数 | 作用 | 示例 |
|---|---|---|
s/// | 替换每行第一个匹配 | sed 's/old/new/' file |
/g | 全局替换该行所有匹配 | sed 's/old/new/g' file |
/2 | 只替换每行第 2 个匹配 | sed 's/old/new/2' file |
/I | 忽略大小写匹配 | sed 's/old/new/I' file |
-i | 原地编辑(无备份,不可撤销) | sed -i 's/old/new/g' file |
-i.bak | 原地编辑并保留 .bak 备份 | sed -i.bak 's/old/new/g' file |
自定义分隔符 | | 模式含 / 时免转义 | sed 's|/old/|/new/|g' file |
Nd / 'N,Md' | 删除第 N 行 / 第 N 到 M 行 | sed '5,10d' file |
/pat/d | 删除匹配模式的行 | sed '/^#/d' config |
Ni / Na | 在第 N 行前插入 / 后追加 | sed '5a\new text' file |
-n "Np" | 只打印指定行(不自动输出) | sed -n '5,10p' file |
/start/,/end/s/// | 只在指定范围内替换 | sed '/start/,/end/s/old/new/g' file |
\( \) 与 \1 | 捕获组与反向引用(BRE) | sed 's/\(pattern\)/\1/g' file |
-E | 扩展正则,( ) 无需转义 | sed -E 's/(old)/\1-new/g' file |
N;$!ba;s/\n//g | 删除所有换行符合并全文 | sed ':a;N;$!ba;s/\n//g' file |
易错点与避坑指南
现象替换含路径的字符串后 sed 报错或结果为空。
原因分隔符 / 与模式中的路径冲突,需要大量转义。
处置换用其它分隔符:sed "s|/old/path|/new/path|g" file。
现象sed -i 改完文件后内容全空了,无法恢复。
原因模式匹配范围比预期大(如 .* 贪婪匹配整行),且 -i 没有备份。
处置改用 -i.bak 留备份;执行前先不带 -i 看输出确认。
现象只想替换每行第一次出现,结果全被替换了。
原因模式里写了 g 标志,或把 . 当成通配导致匹配多处。
处置去掉 g;字面匹配用 . 转义成 \. 或改用 grep -F 先确认匹配数。
现象macOS 上 sed -i 报错或文件被清空。
原因BSD 版 sed 的 -i 必须跟备份后缀,不能直接 -i。
处置macOS 用 sed -i "" "s/old/new/g" file,或 sed -i.bak(会自动生成 .bak)。
现象反向引用 \1 输出为空或保留了原样。
原因BRE 下捕获组必须写成 \( \),且替换串里写 \1。
处置改用 -E 简化写法:sed -E "s/(old)/\1-new/g" file。
现象删除注释行时把含 # 的正文也删了。
原因/^#/ 只匹配行首是 # 的行,若写成 /#/ 则会删掉所有含 # 的行。
处置用锚定写法 sed "/^#/d";确认后先不带 -d 的 -n 打印查看匹配范围。
现象在 macOS/BSD 与 GNU 之间来回切换,命令行为不一致。
原因两者的 -i、-E 语法与部分扩展选项存在差异。
处置统一用 -E 与 -i.bak 写法,两个平台都能工作;避免依赖 BSD 特有选项。
排障路径
1改文件前先预览结果
sed 's/old/new/g' config.yaml不带 -i 只输出;确认无误后再加 -i.bak 落盘。
2原地修改并保留备份
sed -i.bak 's/old/new/g' f.txt生成 f.txt.bak,出问题可立即回滚。
3清理注释与空行
sed '/^#/d; /^$/d' nginx.conf多条命令用分号分隔,一次扫描完成。
4只在指定范围内替换
sed '/start/,/end/s/old/new/g' file范围模式 /start/,/end/ 可用于删除、替换与打印。
5macOS 上的原地编辑
sed -i '' 's/old/new/g' fileBSD 版 -i 必须带后缀,空串表示不备份;要备份用 -i.bak。
命令示例
干跑确认替换,再原地落盘并留备份
sed 's/localhost/0.0.0.0/g' config.yaml
sed -i.bak 's/localhost/0.0.0.0/g' config.yaml第一行不带 -i 只输出,确认无误后第二行用 -i.bak 落盘并留下 .bak。含 / 的模式把分隔符换成 # 更省心。
输出
server: 0.0.0.0 bind: 0.0.0.0:8080 url: http://localhost/api
在两个标记之间批量替换
sed '/# BEGIN/,/# END/s/old/new/g' config.ini地址区间 /start/,/end/ 限定作用范围,避免误改区块外的同名内容。删除区间用 sed '/start/,/end/d'。
输出
managed-by-tool
合并相邻两行
sed -n 'N;s/\n/ /;P;D' data.txtN 把下一行读进模式空间,s 把换行换成空格。sed 的多行处理语法较绕,简单的连续行合并也可以用 paste -sd ' ' 更直观。
输出
first line second line
常见坑与注意事项
- sed -i 无备份且不可回退,先跑不带 -i 的版本确认输出,再用 -i.bak。
- sed 默认 BRE,\+ \| \( 不是特殊字符,需要 -r 切扩展正则。
- 模式含 / 时与分隔符冲突,改用 # 或 | 作分隔符。
- 范围删除 sed '/start/,/end/d' 在只有起始标记没有结束标记时会删到文件末尾。
- sed 不修改原文件内容的语义,切勿指望它做业务逻辑;复杂处理该用 awk 或脚本。
提示
- sed -i 直接修改文件前先备份(-i.bak),或先不加 -i 预览结果。
- sed 默认使用 BRE(基本正则),+、?、| 需转义或用 -E 启用 ERE。
- macOS 的 sed -i 必须跟备份后缀(如 -i ""),Linux 可直接 -i。
- sed -i 's/^/ /' 在每行前加两个空格做缩进展示,配合 -n '${=};p' 可同时输出行号与内容,调试脚本时很直观。
- sed -n '/<开始标记>/,/<结束标记>/p' 只打印两个标记之间的行,是从配置或日志里截取中间段落的常用手法。
- 用 sed -E 's/[[:space:]]+$//' 清理行尾空白比 tr -d 更安全,它只动行尾而不会破坏行内缩进。
常见问题
sed 替换里的 g 标志不加会怎样?
不加 g 时,sed 只替换每一行中第一次匹配到的内容。比如一行里有三个 old,sed 's/old/new/' 只会把第一个换掉,后面两个保持原样。要全部替换必须写成 s/old/new/g。这在只想改链接里第一个端口号之类的场景反而有用。
sed 怎么按行号范围操作?
用 Np 或 Nrange:sed -n '5,10p' file 只打印 5 到 10 行,sed '5,10d' file 删除 5 到 10 行。组合形式 sed '/start/,/end/d' file 删除从匹配 start 到匹配 end 之间的所有行,按模式匹配比按行号更适合结构不固定的文件。
sed 的 s 和 d、i、a 分别做什么?
s 是替换(substitute),把匹配到的内容换成新的;d 是删除(delete)整行;i 是在匹配行之前插入,a 是在之后追加。它们的区别在于 s 保留原行只改内容,d 直接丢弃该行,i/a 则行数会变多。组合使用如 sed '/^#/d; /^$/d' nginx.conf 用分号串起多条命令,一次删除注释行和空行。
sed 可以跨行处理吗?
可以,但语法稍绕。N 会把下一行读进模式空间,配合 s/\n/ / 可以把两行合并成一行;反过来 sed ':a;N;$!ba;s/\n//g' file 能删掉文件里所有换行符,把整个文件压成一行。GNU sed 还支持 -z 让 N 按空字符而非换行分割,处理本身就不含换行的压缩数据时很有用。
为什么 sed 里的正则有时不生效?
多数情况是分隔符冲突:脚本里用了 / 而模式本身也含 /,比如替换 URL 的路径,必须换分隔符写成 s#https://x#http://y#。另外 sed 默认是 BRE,正则的 \+ \| \( 在 BRE 里不是特殊字符,要按基本正则的写法来,或加 -r 切到扩展正则。
由 巧匠 维护
公开更新于 2026年7月21日,内容持续校对官方文档。