sed替换中输出转义引号失效的原因咨询
为什么sed替换中转义引号没生效?
这个问题本质是shell和sed的双重转义解析在搞事情,咱们一步步拆解清楚:
问题根源:两次转义解析
你写的命令是:
stuff='something=something_else' var='new_value'; echo ${stuff} | sed "s/something=\S*/something_new=\\\"${var}\\\"/g"
这里的核心是你用双引号包裹了sed脚本,这会触发两次转义处理:
第一步:Shell先解析双引号内容
Shell会优先处理双引号里的变量和转义字符:
- 变量
${var}被替换成new_value,sed命令变成:s/something=\S*/something_new=\\\"new_value\\\"/g - Shell解析转义:在双引号中,
\\\"会被解析成\"(第一个反斜杠转义第二个反斜杠,得到一个\;第三个反斜杠转义双引号,得到一个")。最终传给sed的实际命令是:s/something=\S*/something_new=\"new_value\"/g
第二步:Sed再解析替换字符串
Sed的替换规则里,\是转义符,所以\"会被sed直接解析成普通的"。这就导致最终输出变成了something_new="new_value",而不是你预期的带转义的格式。
解决方案:避免双重转义
有两种简单的办法解决这个问题:
方案1:用单引号隔离sed的转义逻辑(推荐)
单引号会让shell完全不解析内部的内容(除了单引号本身),我们可以把sed的固定部分用单引号包裹,只把变量部分暴露给shell替换:
stuff='something=something_else' var='new_value'; echo ${stuff} | sed 's/something=\S*/something_new=\\\"'"${var}"'\\\"/g'
这样shell只会替换${var}为new_value,不会碰那些反斜杠,传给sed的替换字符串就是something_new=\\\"new_value\\\",sed解析后就会输出你想要的something_new=\"new_value\"。
方案2:在双引号中加倍转义
既然要经过两次转义,那我们给每个需要留给sed的反斜杠再加一层转义,让shell处理后刚好留下sed需要的内容:
stuff='something=something_else' var='new_value'; echo ${stuff} | sed "s/something=\S*/something_new=\\\\\"${var}\\\\\\"/g"
这里\\\\\"会被shell解析成\\\",刚好是sed需要的转义格式,最终也能得到预期输出。不过这种写法可读性差,容易出错,更推荐方案1。
内容的提问来源于stack exchange,提问作者 Mike
相关产品推荐
相关产品推荐

