
我將一個字串替換為另一個包含轉義引號的字串:
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(刪除另一個)都是特別的。
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
。