web-dev-qa-db-ja.com

sedが通常のバックスラッシュに3つのバックスラッシュを必要とするのはなぜですか?

私は興味があります、なぜsedには3 \ただ認識しますか? 2が必要なのは理解できますが、3は必要ありません。

編集:Cygwinを使用した私のWindowsコンピュータでの例は次のとおりです。

echo "sample_input\whatever" | sed "s/\\\/\//"

バックスラッシュを3つ追加しないと、

sed: -e expression #1, char 7: unterminated s' command
41
Geo

VistaとCygwin 1.7.0を使用して、この動作を再現できました。

  • 2つのバックスラッシュはエラーを生成します
  • eitherthreeor4つのバックスラッシュが機能する
  • 5は同じエラーを与えます

シェルでは2つのバックスラッシュが単一のバックスラッシュになり、sedで中間の区切り文字であるスラッシュをエスケープします。

\\/ -> \/ (which makes the forward slash a regular character instead of a delimiter)

そのうち3つ:最初の2つはシェルで1つになり、3つ目はsedでエスケープします

\\\/ -> \\/

4:シェルで各ペアが1つのペアになり、最初の結果のペアがsedの2番目のペアをエスケープします

\\\\/ -> \\/ 

編集:

ああ、私は一重引用符と二重引用符の両方が私にとって同じように働いたことを言うのを忘れていました(cmd.exeは、Bashなどが行う区別を行いません。

41

シェル(おそらくbash)は独自のエスケープを行っているため、混乱を招きます。 echoコマンドを使用して、何が渡されているかを確認できます。または、カスタムプログラム(一般に「showargs」など)を簡単に作成できます。

 $ echo "s /\\\/\//"
 s /\\/\//
$ echo" s/\\/\ // "
 s /\/\//

単一引用符を使用することもできます。これは、bashで異なる方法で処理されます。

12
Roger Pate

これは、shの二重引用符で囲まれた文字列解析ルールによるものです。

Posix は、shが二重引用符で囲まれた文字列を解析する方法を指定します。

バックスラッシュは、特殊と見なされたときに次の文字のいずれかが続く場合にのみ、エスケープ文字(エスケープ文字(バックスラッシュ)を参照)としての特別な意味を保持します:$ `" \

つまり、shは、バックスラッシュの後に$ '"以外の文字が続きます。

したがって、shが二重引用符で囲まれた文字列sed "s/\\\/\//"に一致する場合、shは次のように解析します。

  1. 最初の2つの\\\に変更されます。最初の\の後に2番目の\が続くためです。
  2. 3番目と4番目の\はまだ文字列に残っています。両方の後に/が続くため、二重引用符で囲まれた文字列では特別ではありません。

Pasring後、shは文字列s/\\/\//sedに渡し、\の最初の出現を/に置き換えます。

同じ理由で、shが文字列に一致すると、"sed s/\\\\/\//"sh/\\/\//sedに渡します。これは、最初の\から/へ。

6
MS.Kim

あなたが将来持っているものの例を示してください。 sedで、「\ "パイプ(|)付き、たとえば

$ cat file
asklfja \ asf

$ sed 's/\\/|/g' file
asklfja | asf

$ sed 's%\\%|%g' file #using different delimiter
asklfja | asf

一度エスケープするだけです。

編集:@OPの例では、bash/kshではなくcmd.exeを使用しているため、cmd.exeは一重引用符を好みません。シナリオを作成できません。これは、GNU 2つのスラッシュを使用するウィンドウのsedで機能します

例えば

C:\test>echo "sample_input\whatever" | sed "s/\\/\//"
"sample_input/whatever"
4
ghostdog74

私のバージョンのCYGWINでは、元のポスターにあるように機能しますが、一重引用符を使用すると動作が異なります(通常)。

 $ echo "sample_input\whatever" | sed 's /\\/\//'
 sample_input/whatever 
 $ echo "sample_input\whatever" | sed "s /\\/\//"
 sed:-e expression#1、char 7:未終了の` s 'コマンド

うーん.

1
James K

Cygwinで1つのバックスラッシュを2つに置き換えるには、次の式が必要です。

sed -e "s | \\ | \\\\ | g"

0
OutputLogic

\\\nまたは\\\t 3つのバックスラッシュとしてありますが、実際には2つのバックスラッシュと別のパターン

   backslash          \\
   newline            \n
   tab                \t

また、/s/...//は、オープンパーツとクローズパーツに使用しています。

そう /\\\/\// だろう \\ + \/ + \/更新された例による

0
YOU