sed -i 是linux下批量替换文本的首选方案,支持原地修改,但gnu与bsd语法不同;需注意转义、分隔符选择、备份机制及复杂场景用awk更稳妥。

用 sed -i 直接修改文件内容最常用
Linux 下批量替换文本,sed -i 是首选方案,它能原地修改文件,不用中转临时文件。但注意:sed -i 在不同系统行为略有差异——GNU sed(Linux)支持直接写入,而 BSD sed(macOS)要求带空后缀,比如 sed -i ''。
常见写法:
sed -i 's/旧文本/新文本/g' file1.txt file2.txt
关键点:
-
s///g中的g表示全局替换(否则只换每行第一个) - 若旧文本含
/,可换分隔符,比如s|/path/to|/new/path|g - 正则特殊字符(如
.、*、[)需转义,否则按正则匹配,不是字面替换 - 想先预览效果?去掉
-i,只运行sed 's/.../.../g' file.txt看输出
处理多个文件时用 find + sed 避免手动列名
当要替换当前目录及子目录下所有 .conf 文件里的文本,硬写一堆文件名不现实,find 是标准解法。
典型组合:
find . -name "*.conf" -exec sed -i 's/localhost/127.0.0.1/g' {} +
说明:
-
{} +比{} \;更高效,会把多个文件一次性传给 sed,减少进程启动次数 - 如果路径含空格,用
-print0 | xargs -0更安全,但多数配置场景无需过度复杂化 - 先测试:把
sed -i换成echo "will process: {}"或加| head -5看前几个匹配结果
需要正则或跨行匹配时,awk 更可控
当替换逻辑变复杂——比如“把注释掉的某配置项取消注释”,或“把两行合并成一行”,sed 容易写错且难调试,awk 的字段和状态管理更清晰。
例如:取消所有以 # server.port= 开头的行的注释
awk '{ if (/^# server\.port=/) sub(/^# /, ""); print }' file.txt > tmp && mv tmp file.txt
注意:
-
awk默认不支持就地编辑,必须重定向再覆盖,或者用gawk -i inplace(GNU awk 4.1.0+) - 点号
.在正则里是通配符,要匹配字面意义的点,得写成\. - 对大文件,
awk内存占用比sed高,纯字符串替换还是优先sed
误操作后恢复不了?备份永远比后悔快一秒
sed -i 没有撤销机制,一旦替换出错(比如正则写太宽泛,把不该动的也改了),原始内容就丢了。
稳妥做法只有两个:
- 加备份后缀:
sed -i.bak 's/foo/bar/g' *.txt→ 会生成file.txt.bak - 用版本控制:
git status确认都是已跟踪文件后,替换完git diff快速核对,有问题git checkout -- *.txt一键回退
别信“我记得原来啥样”,尤其是批量改配置时,一个点号没转义,可能让整个服务起不来。










