预期输入:开始=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
作为循环的“主体” for
。call
变量扩展在内部“正常”发生。观察:
@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 的环境中。first
last
setlocal
endlocal
最后,我要重复@VasiliSyrakis 所说的话:如果你能避免使用cmd.exe
,那么一定要避免。我倾向于批量编写大量内容,但不可否认的是,这有点像用螺丝刀敲钉子很多的问题。