批处理:&符号导致 findstr 出现问题
batch: ampersand causing issues with 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%)\""
这仅添加引号并在搜索表达式中也使用引号
另一种选择是使用延迟扩展,这需要使用 /v:on
选项的显式 cmd
。
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%)"
这部分工作正常,直到文件名中有一个符号,在这种情况下,它会完全崩溃我的脚本。
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%)\""
这仅添加引号并在搜索表达式中也使用引号
另一种选择是使用延迟扩展,这需要使用 /v:on
选项的显式 cmd
。
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%)"