shell变量替换靠参数扩展(如${var//old/new}),文件替换用sed(-i就地修改,需注意macos差异),安全起见先备份再替换,并可用while循环处理多行条件替换。

Shell变量本身不直接支持字符串替换操作,但可以通过参数扩展(Parameter Expansion)或外部命令(如 sed、awk)实现关键字替换,从而完成配置修改。关键在于区分“变量内替换”和“文件内容替换”两种常见场景。
用参数扩展在变量中替换关键字
适用于已将配置内容读入变量,需在内存中修改再写回的场景。Shell原生命令即可完成,无需调用外部程序。
-
单次替换(第一个匹配):
${var/pattern/replacement},例如:line="host=localhost port=3306"; echo ${line/localhost/192.168.1.100}
输出:host=192.168.1.100 port=3306 -
全局替换(所有匹配):
${var//pattern/replacement},注意双斜杠:text="DEBUG=on LOG_LEVEL=on"; echo ${text//on/off}
输出:DEBUG=off LOG_LEVEL=off -
前缀/后缀匹配替换:
${var/#prefix/replacement}(开头)、${var/%suffix/replacement}(结尾),适合精准定位。
用 sed 修改配置文件中的关键字
更常用的是直接编辑配置文件,sed 灵活且支持正则,适合批量或复杂模式。
-
就地替换(修改原文件):
sed -i 's/old/new/g' config.conf
加g标志表示全局;-i在 macOS 上需加空格和备份后缀,如-i.bak -
带上下文的精准替换(避免误改):
sed -i 's/^host[[:space:]]*=[[:space:]]*.*/host = 10.0.0.5/' config.ini
利用^锚定行首,[[:space:]]*匹配任意空白,确保只改 host 行的值 -
变量内容参与替换时需用双引号并转义斜杠:
new_ip="172.16.0.20"; sed -i "s|localhost|$new_ip|g" app.conf
改用竖线|作分隔符,避免 IP 中的点号和斜杠引发混淆
安全修改配置:先备份再替换
生产环境务必保留原始配置,防止替换出错无法回退。
- 使用
sed -i.bak自动生成备份(Linux 和 macOS 兼容写法需注意差异) - 手动备份更可控:
cp config.conf config.conf.$(date +%s).bak,再执行替换 - 替换后建议校验:
grep "target_key" config.conf | head -3或用diff对比备份
进阶:结合 read + while 处理多行配置
当需要按条件替换某几行(如只改特定 section 下的 key),纯 sed 较难,可用 shell 循环控制逻辑。
- 逐行读取,识别 section,再对后续行做条件替换:
while IFS= read -r line; do<br> if [[ $line =~ ^\[database\]$ ]]; then in_db=1; echo "$line"; continue;<br> elif [[ $line =~ ^\[.*\]$ ]]; then in_db=0; echo "$line"; continue;<br> elif [[ $in_db -eq 1 && $line =~ ^host[[:space:]]*= ]]; then echo "host = 10.10.10.10"; else echo "$line"; fi;<br> done config.new
- 处理完重命名覆盖,比单条 sed 更健壮,适合 INI/TOML 类格式











