![](/img/trans.png)
[英]Why won't my batch files run since I changed a Windows “Environment Variable”?
[英]In Windows Batch, why a for loop surrounded by parenthesis won't expand a variable it's told to echo?
在我的项目中,我需要使用findstr
从命令解析多行 output 。 为此,我按照这个答案创建了一个行数组并使用for
循环逐一echo
它们:
(for /L %n in (1 1 %info_count%) do echo %info[%n]%)| findstr /R /C:"[0-9s]: [0-9]" /C:"bytes"
问题是这会导致echo
部分输出%info[1]%
、 %info[2]%
等等。
然而,删除第一组括号会导致for
循环的do
部分解释echo
和管道部分,这意味着不是通过一个echo
获得六个echo
输出,而是通过六个不同的管道。
是什么导致了这个问题?
PS:上面的片段正是我在整个脚本运行后在结果提示中调查的内容。 在主项目中,自然我对变量使用延迟扩展,并在批处理文件的循环内使用适当的变量(即setlocal enabledelayedexpansion
, !var!
和%%a
编辑:根据jeb 的回答,我添加了一个更长的片段,以及我认为问题在于findstr
是一个外部 exe 的理解。
for /f %%d in ('^(for /L %%n in ^(1 1 !info_count!^) do echo !info[%%n]!^)^| ^(findstr /R /C:"[0-9s]: [0-9]" /C:"bytes"^)^| find /c /v ""') do (
if [%%d]==[0] (
...
) else (
...
它的目的是分析mkvmerge -i
的 output ,一个已放入数组( !info1!
, !info2
等)的多行文本,使用findstr
检测两个所需匹配项之一,然后使用find
到 output 的数量匹配,这将决定下一行中的行为。
我试图通过所有这些实现的是避免多次启动 mkvmerge,但是我已经有了一个可行的替代方案,它只是再次调用 mkvmerge 而不是for /l
循环(这意味着双管道在另一种情况下工作) .
在命令行上测试它没有用,因为行为与批处理文件不同。
这里的主要问题是百分比膨胀。 它在解析块时被扩展!
下一个问题是百分比表达式的嵌套不能以这种方式完成。 %info[%n]%
分为%info[%
和n]%
。
在批处理文件中,您将使用延迟扩展来避免所有这些问题。
(for /L %%n in (1 1 !info_count!) do echo !info[%%n]!) | findstr /R /C:"[0-9s]: [0-9]" /C:"bytes"
但它仍然失败,因为您将延迟扩展的块传递给findstr
。 管道使用默认配置启动两个子 cmd.exe 进程,然后再次禁用延迟扩展。 为什么在管道代码块中延迟扩展会失败?
您可以将 findstr 移动到块中,然后将!info[%%n]!
将在传输到新的 cmd.exe 实例之前进行扩展。
for /L %%n in (1 1 !info_count!) do (
echo !info[%%n]! | findstr /R /C:"[0-9s]: [0-9]" /C:"bytes"
)
这会更慢,因为它会为每个循环启动 findstr 和 pipe。
在您提供其他信息后:
括号findstr
在这里没有帮助,因为那不是你的问题。
如果您直接启动findstr
或在 cmd.exe 实例中启动 findstr 不会改变行为,那么只有在管道findstr
部分中存在百分比扩展时才需要该技巧。
如果您只想计算匹配项,则无需find
即可完成。
set /a match_cnt=0
for /L %%n in (1 1 %info_count%) do (
echo !info[%%n]! | findstr /R /C:"[0-9s]: [0-9]" /C:"bytes" > nul
if !errorlevel! == 0 set /a match_cnt+=1
)
echo matches: !match_cnt!
您还可以修改初始代码以使用:
(
for /L %%n in (1 1 %info_count%) do @(
cmd /V:on /C echo !info[%%n]!
)
) | findstr /R /C:"[0-9s]: [0-9]" /C:"bytes"
或者没有(慢)调用cmd /v:on
call echo %%^^info[%%n]%%
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.