sed式でバックスラッシュと二重引用符(二重引用符で囲む)をエスケープします。

sed式でバックスラッシュと二重引用符(二重引用符で囲む)をエスケープします。
$ echo 'output: " ' | sed "s/\"/\"/"
output: "

$ echo 'output: " ' | sed "s/\"/\\\"/"
output: "

$ echo 'output: " ' | sed "s/\"/\\\\\"/"
output: \"

最初と2番目の例で何が起こっているのか理解したいと思います。私の理解は、式に二重引用符を使用しているためと解釈され、sedと解釈\"されるということです。それでは、なぜ私の2番目の出力ではないのですか?"\\\"\"

私はsedasに一重引用符を使用できることを知っています's/"/\"/'いいえ意図したものと同じように機能し、"に置き換えられます"

なぜ二重引用符がこのように動作するのか本当に疑問に思います。

  • GNU bash、バージョン 5.1.4(1)-リリース(x86_64-pc-linux-gnu)
  • sed (GNU sed) 4.8

答え1

内部にシェル仕様:

2.2.3二重引用符

二重引用符( "")で囲まれた文字は、バックティック、ドル記号、およびバックスラッシュ文字を除いて、二重引用符内のすべての文字のリテラル値を保持する必要があります。

(...)

バックスラッシュは、次の文字(特殊文字と見なされる)の1つが続く場合にのみエスケープ文字としての特別な意味を維持する必要があります。
$ ``\ <newline>

だから、

ケース シェルの前(あなたが見るもの) シェル後(Sedから)
1 "s/\"/\"/" s/"/"/
2 "s/\"/\\\"/" s/"/\"/
サム "s/\"/\\\\\"/" s/"/\\"/

存在するsed仕様s発注する:

エスケープされていないバックスラッシュの後に「&」以外の文字、バックスラッシュ、数字、改行文字、またはこのコマンドで使用される区切り文字が続く意味は指定されません。

したがって、ケース2では出力は指定されません(つまり、Sed実装はこれらのケースを自由に解釈できます)。 GNU Sedは、\rキャリッジリターンのための改行\nなどを含むいくつかの特殊文字を提供することによって、この自由を活用します。ドキュメントの完全なリスト)。\"そのうちの1つではなく、単にバックスラッシュを削除することを選択します。その結果、ケース2はGNU Sedのケース1と同じです。

関連情報