sed复杂替换的关键在于精准匹配与正确转义:需明确匹配目标和替换逻辑,善用地址范围、标志位及扩展正则(-r),并注意元字符转义、分隔符选择与跨行处理。

sed 配合正则表达式做复杂替换,关键在于理解模式匹配逻辑、正确转义特殊字符,并合理使用地址范围与标志位。它不是“写对就能跑”,而是要明确“想匹配什么”和“想怎么改”。
用正则精准定位要替换的内容
基础替换命令 sed 's/旧/新/' 中的“旧”部分支持完整正则语法。比如:
- 替换行首的
config:→CONFIG::用^锚定开头:sed 's/^config:/CONFIG:/' file - 替换以数字结尾的单词(如
item1)→item_1:用[0-9]$匹配结尾数字:sed 's/\([a-z]\+\)\([0-9]\)$/\1_\2/' file(注意分组需加反斜杠转义) - 跳过注释行(以
#开头),只替换非注释行中的old:用地址范围/^[^#]/s/old/new/g
处理含特殊字符的字符串
斜杠 /、点 .、星号 *、括号等在正则中都有含义,直接写会出错。解决方法有两个:
- 用其他分隔符代替默认的
/,比如#或|。要替换路径/usr/local/bin为/opt/bin,写成:sed 's#/usr/local/bin#/opt/bin#g' file,避免反复转义斜杠 - 对必须保留字面义的元字符加反斜杠转义。例如把所有单个句点
.替换为.(中文顿号):sed 's/\././g' file
跨行与上下文感知替换
默认 sed 逐行处理,但可用 N 命令读入下一行,实现跨行匹配:
- 把连续两行
name: xxx和age: yyy合并为一行:sed '/^name:/ { N; s/name: \(.*\)\nage: \(.*\)/NAME:\1 AGE:\2/; }' file - 只替换出现在
section A和section B之间的TODO:sed '/^section A$/,/^section B$/ s/TODO/DONE/g' file
启用扩展正则提升可读性
加 -r(或 --regexp-extended)后,括号、加号、问号等无需反斜杠,写法更接近通用正则习惯:
- 匹配一个或多个字母后跟数字:
sed -r 's/[a-zA-Z]+[0-9]+/ID/g' file - 用命名捕获?不行 —— sed 不支持命名捕获,但可用
\1\2引用分组:sed -r 's/(https?):\/\/([^\/]+)/\1:\/\/REDACTED/g' file
不复杂但容易忽略:正则是否贪婪、是否区分大小写(加 I 标志)、是否影响多行(需配合 N 或 -z 处理 null 分隔),这些细节决定替换成败。


















