
文字列をエスケープされた引用符を含む別の文字列に置き換えます。
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
は\
、シェル (1 つを削除) と sed (もう 1 つを削除) の両方にとって特別なものです。sed に実際に必要なものを理解させるには、sed に次の文字列を与える必要があります。
s~FOO~test\\\"test~g
これを sed は に変換しますtest\"test
。これが必要なことです。
すると、シェルは、すべての二\
重引用符と"
引用符\"
(つまり 7 \
) が付いた二重引用符で囲まれた文字列を受け取ることになります。
sed "s~FOO~test\\\\\\\"test~g"
これはシェルによって "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
これは\
( と書かれた\\
)を三つ \
( と表記されます\\\\\\
)。
置き換えは次のように機能します:
$ echo "replace FOO" | sed -e 's~FOO~'"${var//\\/\\\\\\}"'~g'
これはない\
変数内の任意の値に対する一般解。
一般的な解決策
一般的な解決策では、すべてを二重にして\
からすべての二重引用符をエスケープするために 2 つのパスが必要になります。
$ 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
。