【问题标题】:batch: ampersand causing issues with findstr批处理:&符号导致 findstr 出现问题
【发布时间】:2017-12-11 07:17:31
【问题描述】:

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

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

我不能只将文件名放在引号中,因为我需要在开头找到字符串。那我该怎么做呢?

【问题讨论】:

    标签: batch-file batch-processing findstr


    【解决方案1】:

    命令行使用:

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

    在批处理文件中

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

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

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

    替代解决方案:

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

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

    【讨论】:

    • 转义、双重转义、强制双重解析、延迟扩展……有时我还是很惊讶工作确实可以完成……
    • 谢谢! ..我学习斯蒂芬提到的所有事情的第一步。
    • 替代解决方案在 Win 10 上对我不起作用。初始解决方案可以。
    【解决方案2】:

    另一个选项是使用延迟扩展,这需要一个显式的 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% 失败
    • @jeb - 我假设批处理脚本中没有启用延迟扩展。但是是的,如果批处理启用了延迟扩展,则需要左侧的外括号。
    猜你喜欢
    • 2017-05-06
    • 1970-01-01
    • 2010-12-30
    • 2021-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-26
    • 1970-01-01
    相关资源
    最近更新 更多