为什么sed需要3个反斜杠才能获得常规反斜杠?

时间:2010-03-03 06:58:16

标签: regex sed

我很好奇,为什么sed需要3 \来识别一个?我明白它需要2,但我不知道。

编辑:这是我的Windows计算机上的一个例子,使用Cygwin:

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

如果我不添加3个反斜杠,我会得到一个

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

7 个答案:

答案 0 :(得分:41)

我能够使用Vista和Cygwin 1.7.0重现这种行为。

  • 两个反斜杠产生错误
  • 三个四个反斜杠工作
  • Five给出了同样的错误

两个反斜杠在shell中成为一个反斜杠,然后在sed中转义正斜杠,即中间分隔符。

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

其中三个:前两个在shell中成为一个,然后在sed中逃脱第三个

\\\/ -> \\/

四:每一对在shell中成为单一对,然后第一个结果在sed

中逃脱第二对
\\\\/ -> \\/ 

修改

哦,我忘了说单引号和双引号对我来说都是一样的(cmd.exe并不能说明Bash等人的区别。)

答案 1 :(得分:12)

你的shell(可能是bash)正在进行自己的转义,这让你感到困惑。您可以使用echo命令查看传递的内容,或者编写自定义程序(通常命名为“showargs”或类似程序)很容易:

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

您也可以使用单引号,在bash中区别对待。

答案 2 :(得分:6)

这是由sh的双引号字符串解析规则引起的。

Posix指定sh如何解析双引号字符串。

  

反斜杠应保留其特殊含义作为转义字符(请参阅转义字符(反斜杠)),只有在被认为是特殊时后跟下列字符之一:   $`“\

换句话说,sh留下反斜杠,后跟$'“以外的字符。

因此,如果sh符合双引号字符串sed "s/\\\/\//"sh会按如下方式解析它。

  1. 前两个\\已更改为\。因为第一个\后跟第二个\
  2. 第三个和第四个\仍留在字符串中。因为它们都跟在/之后,这在双引号字符串中并不特殊。
  3. 在引用后,sh将字符串s/\\/\//传递给sed,将\的第一次出现替换为/

    同样的推理,当sh符合字符串时,"sed s/\\\\/\//"sh会将/\\/\//传递给sed,这也会替代\的第一次出现/ 1}}进入{{1}}。

答案 3 :(得分:4)

请展示您将来拥有的一个例子。在sed中,假设您要用管道(|)替换“\”,例如

$ cat file
asklfja \ asf

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

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

你只需要逃脱一次。

编辑:对于@ OP的示例,由于您使用的是cmd.exe而不是bash / ksh,因此cmd.exe不喜欢单引号。我无法制作你的场景。这适用于我使用2斜杠的Windows上的GNU sed

例如

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

答案 4 :(得分:1)

在我的CYGWIN版本中,它可以像原始海报所说的那样工作,但如果我使用单引号,则工作方式不同(通常情况下)。

$ echo "sample_input\whatever" | sed 's/\\/\//'
sample_input/whatever
$ echo "sample_input\whatever" | sed "s/\\/\//"
sed: -e expression #1, char 7: unterminated `s' command

嗯..

答案 5 :(得分:0)

我想,你假设\\\n\\\t为三个反斜杠,但实际上,它有两个反斜杠和另一个模式

   backslash          \\
   newline            \n
   tab                \t

另外,/可能需要转义,因为在s/.../中,/用于打开和关闭部分。

根据您更新的示例<{1}} /\\\/\//

答案 6 :(得分:0)

在我的Cygwin上用两个反斜杠替换一个反斜杠需要这个表达式:

sed -e“s | \\ | \\\\ | g”