batch:ampersand导致findstr的问题

时间:2017-07-07 05:32:07

标签: batch-file batch-processing findstr

这部分很有效,直到文件名中有一个&符号,在这种情况下它会完全崩溃我的脚本。

echo %filename% | findstr /i /b /c:"%name% (%year%)"

我不能把文件名放到引号中,因为我需要在开头找到字符串。那我怎么能两个都做?

2 个答案:

答案 0 :(得分:5)

对于命令行使用:

echo %file^name:^&=^^^&% | ...

批处理文件

echo %%filename:^&=^^^&%% | ...

如何运作?
当管道创建两个新的cmd.exe实例时,echo ...将被解析两次 诀窍是仅在第二次扩展中扩展文件名 然后使用&展开并替换^&以避免&出现问题。
插入符将用于逃脱&符号,并且其本身将被移除 在第二次扩展中,解析器只看到echo %filename:&=^&%

要强制扩展到第二个解析步骤,批处理文件的百分号必须加倍 从命令行,这不起作用,但变量名称中的任何位置都有一个简单的插入符号。

替代解决方案:

echo "%filename%" | findstr /i /b /c:^"\"%filename% (%year%)\""

这会简单地添加引号并在搜索表达式中使用引号

答案 1 :(得分:3)

另一种选择是使用延迟扩展,这需要使用cmd选项明确/v:on

cmd /v:on /c "(echo !filename!)" | findstr /i /b /c:"%name% (%year%)"

如果您的批处理脚本已启用延迟扩展,则需要左侧的括号以防止在父脚本(请参阅Why does delayed expansion fail when inside a piped block of code?中发生延迟扩展。

支持子进程仍默认为禁用延迟扩展,因此仍需要cmd /v:on /c ...

@echo off
setlocal enableDelayedExpansion
...
(cmd /v:on /c "(echo !filename!)") | findstr /i /b /c:"%name% (%year%)"

延迟扩展直到子进程逃避扩展的另一种方法

@echo off
setlocal enableDelayedExpansion
...
cmd /v:on /c "(echo ^!filename^!)" | findstr /i /b /c:"%name% (%year%)"