我很好奇,为什么sed需要3 \
来识别一个?我明白它需要2,但我不知道。
编辑:这是我的Windows计算机上的一个例子,使用Cygwin:
echo "sample_input\whatever" | sed "s/\\\/\//"
如果我不添加3个反斜杠,我会得到一个
sed: -e expression #1, char 7: unterminated s' command
答案 0 :(得分:41)
我能够使用Vista和Cygwin 1.7.0重现这种行为。
两个反斜杠在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
会按如下方式解析它。
\\
已更改为\
。因为第一个\
后跟第二个\
。\
仍留在字符串中。因为它们都跟在/
之后,这在双引号字符串中并不特殊。在引用后,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”