这部分运行良好,直到文件名中有一个&符,在这种情况下,它完全崩溃了我的脚本。批处理:导致与findstr相关的问题
echo %filename% | findstr /i /b /c:"%name% (%year%)"
我不能只是把文件名放在引号中,因为我需要在开头找到字符串。那么我该怎么做呢?
这部分运行良好,直到文件名中有一个&符,在这种情况下,它完全崩溃了我的脚本。批处理:导致与findstr相关的问题
echo %filename% | findstr /i /b /c:"%name% (%year%)"
我不能只是把文件名放在引号中,因为我需要在开头找到字符串。那么我该怎么做呢?
用于命令行:
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%)"
逃逸,双重转义,迫使双解析,延迟扩展......有时我仍然感到惊讶那项工作的确可以做... – Stephan
谢谢! ..我首先学习stephan提到的所有事情。 (cmd/v:on/c“(echo!filename!)”)| – bricktop