我将一个字符串替换为另一个包含转义引号的字符串:
echo "replace FOO" | sed -e "s~FOO~test\\\"test~g"
我所期望的是看到replace test\"test
。相反,我看到了replace test"test
。
我怎样才能sed
包含我的转义序列?
答案1
反斜杠是双引号内和替换中的转义字符sed
。因此"\\\""
,sed 可以看出\"
它的含义"
尝试单引号:
echo "replace FOO" | sed -e 's~FOO~test\\"test~g'
或双重转义:
echo "replace FOO" | sed -e "s~FOO~test\\\\\"test~g"
答案2
An\
对于 shell(删除一个)和 sed(删除另一个)都是特殊的。要让 sed 了解实际需要什么,您需要向 sed 提供以下字符串:
s~FOO~test\\\"test~g
哪个 sed 将转换为test\"test
,这就是您所需要的。
然后 shell 应该接收一个双引号字符串,其中每个\
双引号和"
引号\"
(即 7 \
):
sed "s~FOO~test\\\\\\\"test~g"
shell 将其转换为 "s~FOO~test\\"test~g" 并且 sed 将使用s~FOO~test\"test~g
.
或者,更简单一点,使用单引号'
(仅 3 \
):
sed 's~FOO~test\\\"test~g'
添加
在评论中您说:“我实际上是用环境变量替换内部文本”和“不幸的是我的变量包含双引号和单引号”
那么,将变量设置为您希望 sed 接收的值,例如:
$ var='test\'\''test\"test'; echo "$var"
test\'test\"test
并且,如果斜杠仅用于转义引号,请用此修改变量(假设 bash,便携式解决方案需要更多工作):
$ echo "${var//\\/\\\\\\}"
test\\\'test\\\"test
这会将 1 \
(写为\\
)转换为三 \
(写为\\\\\\
)。
替换将如下所示:
$ echo "replace FOO" | sed -e 's~FOO~'"${var//\\/\\\\\\}"'~g'
这是不是\
任何变量的通用解决方案。
通用解决方案
一般的解决方案需要两次传递来将所有双引号加倍\
,然后转义每个双引号:
$ var='test\'\''test\"test aa\\\"bb\\\\\'\''cc\'\'
$ echo "$var"
test\'test\"test aa\\\"bb\\\\\'cc\'
然后修改var
:
$ var=${var//\\/\\\\}; var=${var//\"/\\\"}; echo "$var"
test\\'test\\\"test aa\\\\\\\"bb\\\\\\\\\\'cc\\'
替换将像这样工作:
$ echo "replace FOO" | sed -e 's~FOO~'"$var"'~g'
replace test\'test\"test aa\\\"bb\\\\\'cc\'
正是变量的原始内容var
。