![为什么在 Windows 上 sed 替换需要三个反斜杠](https://linux22.com/image/1351184/%E4%B8%BA%E4%BB%80%E4%B9%88%E5%9C%A8%20Windows%20%E4%B8%8A%20sed%20%E6%9B%BF%E6%8D%A2%E9%9C%80%E8%A6%81%E4%B8%89%E4%B8%AA%E5%8F%8D%E6%96%9C%E6%9D%A0.png)
指的是这问题:
为什么\
在cmd.exe
使用sed
(MinGW msys-1.0)时需要一个额外的字符,而根据(参见最后一段或)\
不是一个特殊字符cmd /?
这里)?
以下特殊字符需要用引号引起来:& < > [ ] { } ^ = ; ! ' + , ` ~ [空格]
第一个反斜杠转义了第二个反斜杠,剥夺了它的特殊含义。剩下的两个反斜杠sed
通过使用第二个反斜杠转义了第三个反斜杠,所以最后只剩下一个逐字的单个反斜杠,我的搜索和替换匹配了它。但我仍然对这个解释不满意,因为:
cmd 不执行标记,因此转义的第一步没有意义......来自这里,\
只有在前面时才具有一些特殊含义"
……那么真正的解释是什么?
在Linux中的bash上:
echo 'sample\input' | sed 's/\\/----/'
sample----input
cmd.exe
在 Windows XP SP3上('
不需要):
echo sample\input | sed "s/\\/----/"
sed: -e expression #1, char 9: unterminated 's' command
// for some reason sed received only one backslash which causes him trouble ?
echo sample\input | sed "s/\\\/----/"
sample----input
答案1
Sed 正在执行此操作,它在“查找”部分中使用正则表达式。它根据开关使用 BRE 或 ERE 或 PCRE。反斜杠在正则表达式中是特殊的。
添加
我没有使用您使用的单引号版本,因为对我来说,这在 cmd.exe 中毫无意义!cmd.exe 使用的是双引号。
而且它运行良好。
使用 gnuwin32 的 sed 从 cmd.exe 运行进行测试,正如预期的那样。
C:\>echo sample\input | sed "s/\\/----/"
sample----input
C:\>sed --v
GNU sed version 4.2.1
Copyright (C) 2009 Free Software Foundation, Inc.
如果我正在测试 cygwin 的 sed,我会从 cygwin 窗口运行它,因为 cygwin 程序应该在那里运行。然后我会使用单引号。从这个意义上说,msys 似乎与 cygwin 类似。
更新
您可以从 cmd 或 cygwin 运行 cygwin 的 sed。它们的行为不同,因为它们是不同的 GNU 版本,但我没有看到从 cmd 运行与从 cygwin 运行有任何与 shell 相关的问题(除了关于 cygwin 的单引号(例如 bash)和 cmd 的双引号的简单问题)。
而且 cygwin 的 sed 版本要比 sed 更新很多。Gnuwin32 的 sed 与许多 gnuwin32 产品(包括 gnuwin32 grep)一样,已经过时很多年了。例如,较新的 grep 可以修复较早 grep 中的错误。gnuwin32 使用的 2009 sed 或 gnuwin32 使用的较不更新的版本可能还可以,但最好使用 cygwin 使用的较新版本。
有趣的是,sed 在反斜杠方面的行为有所不同。我可以看到如何让它在后面的 sed(cygwin 使用的 sed)中工作。
C:\blah>echo a\bc | c:\cygwin\bin\sed "s/\\/_/"
/usr/bin/sed: -e expression #1, char 6: unterminated `s' command
C:\blah>echo a\bc | c:\cygwin\bin\sed "s/\\\/_/"
a_bc
C:\blah>echo a\bc | "c:\Program Files (x86)\GnuWin32\bin\sed" "s/\\/_/"
a_bc
早期的 sed(gnuwin32 的 sed)允许“s/\/_/”,它不会转义正斜杠。因此,反斜杠会转义反斜杠以生成文字反斜杠。两个反斜杠后的正斜杠仍然正常。并且它在这种情况下可以正常工作。
注意:在 cmd 中运行 cygwin 的 sed 是可以的。而且由于它是较新的版本,因此比 gnuwin32 的 sed 更可取。
后面的 sed(cygwin 的 sed)不允许“s/\/_/”,因为 / 转义了正斜杠。直觉(也是正确的直觉)是尝试添加另一个反斜杠,看看会发生什么。而且它有效。不确定机制,但我猜后面的 sed 中的一个反斜杠是\\\
。
C:\blah>echo \ | c:\cygwin\bin\sed "s/\\\/d/"
d