【发布时间】:2017-12-11 07:17:31
【问题描述】:
这部分运行良好,直到文件名中有一个&符号,在这种情况下它会完全崩溃我的脚本。
echo %filename% | findstr /i /b /c:"%name% (%year%)"
我不能只将文件名放在引号中,因为我需要在开头找到字符串。那我该怎么做呢?
【问题讨论】:
标签: batch-file batch-processing findstr
这部分运行良好,直到文件名中有一个&符号,在这种情况下它会完全崩溃我的脚本。
echo %filename% | findstr /i /b /c:"%name% (%year%)"
我不能只将文件名放在引号中,因为我需要在开头找到字符串。那我该怎么做呢?
【问题讨论】:
标签: batch-file batch-processing findstr
命令行使用:
echo %file^name:^&=^^^&% | ...
在批处理文件中
echo %%filename:^&=^^^&%% | ...
它是如何工作的?
当管道创建两个新的 cmd.exe 实例时,echo ... 将被解析两次。
诀窍是仅在第二次扩展中扩展文件名。
然后将& 扩展并替换为^& 以避免& 出现问题。
插入符号将用于转义 & 符号,它本身将被删除。
在第二个扩展中,解析器只看到echo %filename:&=^&%。
要强制扩展进入第二个解析步骤,批处理文件的百分号必须加倍。
在命令行中,这不起作用,但变量名中任何位置的简单插入符号都可以。
替代解决方案:
echo "%filename%" | findstr /i /b /c:^"\"%filename% (%year%)\""
这会在搜索表达式中添加简单的引号并使用引号
【讨论】:
另一个选项是使用延迟扩展,这需要一个显式的 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%)"
【讨论】:
(cmd /v:on /c "(echo !filename!)") | ...。否则 filename=%path% 失败