添加

添加

我将一个字符串替换为另一个包含转义引号的字符串:

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

相关内容