追加した

追加した

文字列をエスケープされた引用符を含む別の文字列に置き換えます。

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

関連情報