sed替换本质是正则匹配而非简单字符替换,需注意分隔符选择、元字符转义、g标志全局替换、-i安全备份等关键点,否则易出错。

sed 替换字符不是“替换单个 ASCII 字符”那么简单——它本质是按正则模式匹配并替换文本片段,所谓“字符”,实际是字符串或正则单元。直接用 sed 's/a/b/' 看似替换单个字符,但背后依赖上下文、分隔符、转义和标志控制。错用会漏替、多替,甚至报错。
替换普通字符串(含字母/数字/下划线)
这是最常见场景,比如把配置里的 DEBUG=true 改成 DEBUG=false。
- 必须加
g标志,否则每行只换第一个匹配项:sed -i 's/true/false/g' config.ini - 不加
-i时只是预览,输出到终端,原文件不动;加了才写回文件 - 若字符串含空格或等号,只要没特殊正则元字符(如
.、*、^),照常处理:sed -i 's/username = admin/username = guest/g' settings.conf
替换含斜杠的路径或 URL
/ 是 sed 默认分隔符,遇到 /usr/bin 或 https://example.com 会语法错误。
- 立刻换分隔符:用
|、#、_等替代,避免反斜杠堆砌:sed -i 's|/usr/local/bin|/opt/bin|g' script.sh - URL 中的
//不用额外转义,只要分隔符不冲突即可:sed -i 's#https://old.com#https://new.com#g' config.json - 别用
/分隔却硬加转义(如s/\/usr\/bin/\/opt\/bin/g),可读性差且易出错
替换带正则元字符的字符串
如果你要替换的“字符”本身是正则符号(如 .、*、[、^),默认会被解释为模式,不是字面量。
- 想字面替换
a.b为x-y,必须转义点号:sed -i 's/a\.b/x-y/g' file.txt - 替换
[error]这种带方括号的字符串,需转义左括号:sed -i 's/\[error\]/[warning]/g' log.txt - 更稳妥的做法:用
printf '%q' 'string'转义后再拼进命令,或改用perl -pi -e(它默认字面匹配)
安全替换前必须备份原文件
一旦 -i 执行出错,原文件内容就没了——特别是批量处理多个文件时。
- 强制加
.bak后缀备份:sed -i.bak 's/foo/bar/g' *.conf,会生成file.conf.bak - 不要依赖“先测试再执行”:测试命令
sed 's/.../.../g' file和真实sed -i的行为可能因编码、换行符、BOM 等产生差异 - 对重要配置,先
cp -r ./configs ./configs.backup整体备份目录,比单个.bak更可靠
真正容易被忽略的,是 正则元字符是否被当作字面量 这一判断。很多人看到 sed 's/./x/g' 想替换成所有点号,结果把每行每个字符都替成了 x——因为 . 在正则里是“任意字符”。这时候你得意识到:你要的不是“替换字符”,而是“替换这个特定符号”,必须转义或换工具。


















