在批处理文件中使用FINDSTR转义反斜杠

3
在我的svn Pre commit hooks中,我使用findstr来阻止提交某些文件类型。现在我想将其扩展到目录上,在第一次尝试中是\obj\目录,但我遇到了正则表达式和转义dir的\的问题。
目前我的代码如下:
"C:\Program Files\VisualSVN Server\bin\svnlook.exe" changed -t %2 %1 | FindStr /R ".obj\\\"
IF %ERRORLEVEL% EQU 1 GOTO OK
echo "obj directories cannot be committed" >&2
exit 1
:OK
exit 0

我已经尝试过仅在结尾处使用 \ ,但这似乎也会转义双引号?有任何想法吗?
6个回答

3

实际上,以下任一命令都可以达到您想要的效果:

... | findstr /R \.obj\\

... | findstr /R "\.obj\\\\"

由于您指定了/R,因此在.之前还需要一个反斜杠,否则它将被解释为通配符。

附注:从我的测试中得出的结论是,findstr.exe使用微软C库使用的有些奇怪的引号规则,这在Microsoft's website上有描述。在这种特殊情况下,相关规则是提到,由偶数个反斜杠前面的双引号字符被解释为一半的反斜杠数。 (是的,这很奇怪,当你意识到cmd.exe也特别对待双引号字符时,它变得更加奇怪......在Windows上正确引用东西是一个痛苦的世界)。


1
在正则表达式中,反斜杠应该被双重转义以便在字符串正则表达式中正确解释:
FindStr /R "\\.obj\\\\"

但是在你的情况下,由于你的正则表达式应该匹配.obj文件和"obj"目录,我建议:

FindStr /R "\\.?obj\\\\?"

因为你原来的正则表达式 (".obj\\") 只会检测到 ".obj" 目录,而不是 "obj"。所以需要在 '.' 前面加上 '\\' 来改变其解释。
由于 '.' 表示任意字符,你还需要在它前面加上 "\\" 来改变其解释。

由于奇怪的引用规则,您提供的示例无法正常工作 - 您需要在任何双引号字符之前将反斜杠的数量翻倍。此外,您应该在“.”字符前面加上反斜杠以指示它应被视为字面值,而不是通配符。 - j_random_hacker
你没有测试过这个,是吗?在点号前面的反斜杠必须是单个反斜杠,如果在最后一个双引号之前加上一个问号,那么末尾的4个反斜杠将变成2个。引用规则非常奇怪,我承认。 - j_random_hacker

1

你遇到了什么错误?

这可能是一个误导,但是SVN使用/作为路径分隔符,在Windows下会引起一些问题。我不得不在所有的钩子脚本中加入以下内容,将/更改为\

SET REPOS=%1

:: Transform forward-slashes to back-slashes for Windows
SET REPOS=%REPOS:/=^\%

1
我使用以下方法解决了这个问题。
:CHECKOBJDIRWITHFILES
"C:\Program Files\VisualSVN Server\bin\svnlook.exe" changed -t %2 %1  > "C:\Repositories\SoftwareRepository\hooks\out.txt"
"C:\Program Files\VisualSVN Server\bin\svnlook.exe" changed -t %2 %1 | FindStr /R ./obj/.
echo %ERRORLEVEL% > "C:\Repositories\SoftwareRepository\hooks\error.txt"
IF %ERRORLEVEL% EQU 1 GOTO CHECKOBJDIRWITHOUTFILES
echo "obj directories and their files cannot be committed" >&2
exit 1
:CHECKOBJDIRWITHOUTFILES
"C:\Program Files\VisualSVN Server\bin\svnlook.exe" changed -t %2 %1  > "C:\Repositories\SoftwareRepository\hooks\out.txt"
"C:\Program Files\VisualSVN Server\bin\svnlook.exe" changed -t %2 %1 | FindStr /R ./obj
echo %ERRORLEVEL% > "C:\Repositories\SoftwareRepository\hooks\error.txt"
IF %ERRORLEVEL% EQU 1 GOTO OK
echo "obj directories cannot be committed" >&2
exit 1
:OK
echo %ERRORLEVEL%  >&2
exit 0

为什么不使用%VISUALSVN_SERVER%环境变量? - bahrep

0
你在这种情况下实际上需要正则表达式吗?如果你只是在搜索子字符串"\obj\",你可以使用/C而不是/R将文本作为文字匹配字符串处理:
{command} | findstr /C:\obj\

0
在findstr包含两个字符序列\"的情况下,搜索字符串必须为\\\\(四个反斜杠)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接