2010-03-03 566 views
29

我很好奇,为什么sed需要3 \只是为了识别一个?我会理解它需要2,但我不知道。为什么sed需要3个反斜杠作为常规反斜杠?

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

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

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

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

显示你有什么 – ghostdog74 2010-03-03 07:00:55

+0

它没有。告诉我们你为什么这么做。 – 2010-03-03 07:01:07

+0

是你的壳消耗额外的反斜杠水平? – p00ya 2010-03-03 07:07:23

回答

31

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

  • 两个反斜杠产生错误
  • 要么或四个反斜杠工作
  • 五给出了同样的错误

两个反斜杠成为壳一个反斜杠,然后在sed逃避中间分隔符的正斜杠。

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

其中三个:前两个成为一个在其壳,然后逃逸在sed

第三个
\\\/ -> \\/ 

四:每对成为壳单者然后将第一所得一个逃逸第二次在SED

\\\\/ -> \\/ 

编辑:

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

+0

但是,如果反斜杠后的字符不是斜线,'s/\\ [0-9] * //'似乎是正确的 – Timo 2018-01-16 13:58:52

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不喜欢单引号。我无法制作你的场景。这适用于我的GNU sed的使用2个窗口斜杠

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

@ ghostdog74,我发布了一个例子。 – Geo 2010-03-03 07:07:40

+0

@geo,看我的编辑 – ghostdog74 2010-03-03 07:19:50

+0

我没有使用bash,ghostdog74和单引号,我得到了同样的错误。 – Geo 2010-03-03 07:26:37

0

我猜,你假设\\\n\\\t三个反斜杠那里,但实际上,它的2个反斜线和另一个模式

backslash   \\ 
    newline   \n 
    tab    \t 

也,/可能需要逃脱,因为在s/...//正在使用的开放和关闭部分。

所以/\\\/\//会根据您的更新例如

+0

我喜欢你的解释方法,你可以看看这个并试着回答它吗?https://superuser.com/questio ns/1249497/sed-needs-n-append-new-line?noredirect = 1#comment1834908_1249497 – 2017-09-12 19:42:23

8

你的外壳(可能的bash)在做自己的逸出\\ + \/ + \/,而这迷惑你。您可以使用echo命令来查看正在传递什么,或者很容易编写自定义程序(通常称为“showargs”或类似):

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

您还可以使用单引号,这是在区别对待庆典。

+0

我使用Windows的'cmd.exe',而不是bash。 – Geo 2010-03-03 07:26:05

+0

@Geo:我猜bash是因为你提到了cygwin,但其他shell也是逃避了。 – 2010-03-03 07:29:35

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 

嗯..

0

更换一个反斜杠有两个在我的Cygwin需要这个表达式:

SED -e “S | \\ | \\\\ | G”

5

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

Posix指定sh解析双引号字符串的方式。

反斜杠应保留其特殊含义的转义字符后仅在由下列字符视为特殊情况下(见转义字符(反斜杠)): $`“\

在换句话说,sh将反斜线后面加上$'“以外的字符。

所以,如果sh符合双引号字符串sed "s/\\\/\//",sh解析它如下。

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

pasring后,sh经过串s/\\/\//sed,其取代的\第一次出现为/

随着相同的推理,当sh满足串,"sed s/\\\\/\//"sh传递/\\/\//sed,这也代用品\第一次出现为/