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

Geo*_*Geo 42 regex sed

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

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

$ echo "sample_input\whatever" | sed "s/\\\/\//"
sample_input/whatever
Run Code Online (Sandbox Code Playgroud)

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

sed: -e expression #1, char 7: unterminated s' command
Run Code Online (Sandbox Code Playgroud)

Pau*_*ce. 41

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

  • 两个反斜杠会产生错误
  • 无论是 3个四个反斜杠工作
  • 五给出了同样的错误

两个反斜杠在shell中成为一个反斜杠,然后在sed中逃脱正斜杠,这是中间分隔符.

\\/ -> \/ (which makes the forward slash a regular character instead of a delimiter)
Run Code Online (Sandbox Code Playgroud)

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

\\\/ -> \\/
Run Code Online (Sandbox Code Playgroud)

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

\\\\/ -> \\/ 
Run Code Online (Sandbox Code Playgroud)

编辑:

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


小智 12

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

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

您也可以使用单引号,在bash中对它们进行不同的处理.


小智 6

这是由于sh双引号字符串解析规则.

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

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

换句话说,sh左边是反斜杠,后跟$'"以外的字符.

因此,如果sh遇到双引号字符串sed "s/\\\/\//",sh则按如下方式解析它.

  1. 前两个\\改为\.因为第一个\ 是第二个\.
  2. 第三个和第四个\仍留在字符串中.因为它们都是后跟的/,这在双引号字符串中并不特殊.

pasring后,sh经过串s/\\/\//sed,其替代品的第一次出现\/.

有了同样的道理,当sh遇到字符串"sed s/\\\\/\//",sh传递/\\/\//sed,这也替换第一次出现\/.