批处理文件中的For循环

批处理文件中的For循环

预期输入:开始=1,结束=500,间隔=100

预期输出:

1, 100

101, 200

201,300

301,400

401,500

@echo off
set start=1
set end=500   
set interval=100
for /L %%g in (%start%, %interval%, %end%) do (
set first=%%g
set /a last=%first% -1 + %interval%
echo %first% , %last%

)

实际产量:

401,401-1+100

401,401-1+100

401,401-1+100

401,401-1+100

401,401-1+100

不确定为什么第一个被分配了 401 值,感谢任何帮助

答案1

这是一个典型的延迟扩展问题。在命令提示符下键入help set或,set /?查看有关延迟扩展的讨论(位于完整帮助的一半以上)。

%var%解析行时会发生正常的使用扩展。问题是您的整个 FOR 循环块在一次传递中被解析。因此,您看到的是循环开始前存在的常量值。401 的值可能是上次运行留下的。

解决方案是延迟扩展。首先,您必须使用 来启用它setlocal enableDelayedExpansion。然后使用!var!而不是%var%。这将在执行时而不是解析时给出值。

此外,使用时无需扩展数字变量set /a

@echo off
setlocal enableDelayedExpansion
set start=1
set end=500
set interval=100
for /L %%g in (%start%, %interval%, %end%) do (
  set /a first=%%g, last=first-1+interval
  echo !first!, !last!
)

答案2

@dbenham 说得对。我会提出一个替代方案。我发现延迟扩展对于较长的子程序来说有点难看和令人困惑,所以我倾向于将一个单独的变量call作为循环的“主体” forcall变量扩展在内部“正常”发生。观察:

@echo off
setlocal
set start=1
set end=500   
set interval=100
for /L %%g in (%start%, %interval%, %end%) do call :_d %%g
endlocal
goto :EOF

:_d
set /a last=%1 - 1 + interval
echo %1, %last%

对于这种特殊情况,确实需要更多的代码,但对于不太简单的批处理文件,我认为这是一个“胜利”。

另外:您没有setlocal/ ,因此和endlocal的值将在执行过程中保持不变(假设您继续在同一个 shell 中运行它们),并在第二次运行代码时给出不同的结果。我倾向于将批处理文件包装在/对中,以防止我在脚本中使用的变量“泄漏”到父 shell 的环境中。firstlastsetlocalendlocal

最后,我要重复@VasiliSyrakis 所说的话:如果你能避免使用cmd.exe,那么一定要避免。我倾向于批量编写大量内容,但不可否认的是,这有点像用螺丝刀敲钉子很多的问题。

相关内容