使用Windows批处理中的FOR循环进行计数

47

有人可以解释一下这个吗?我能够使用Windows命令提示符在循环中进行计数,使用以下方法:

SET /A XCOUNT=0
:loop
SET /A XCOUNT+=1
echo %XCOUNT%
IF "%XCOUNT%" == "4" (
  GOTO end
) ELSE (
  GOTO loop
)
:end

但是这种方法不起作用(它会为文件中的每一行打印出“1”)。 它表现得就像变量超出了范围:

SET /A COUNT=1
FOR /F "tokens=*" %%A IN (config.properties) DO (
  SET /A COUNT+=1
  ECHO %COUNT%
)
3个回答

80

这段代码不能正常工作是因为整个for循环(从for关键字到最后一个闭合括号,包括它们之间的指令)在执行前就已被解释器评估了。

换句话说,在循环开始执行之前,%count%已经被替换成了它的值1

你需要的是像下面这样的代码:

setlocal enableextensions enabledelayedexpansion
set /a count = 1
for /f "tokens=*" %%a in (config.properties) do (
  set /a count += 1
  echo !count!
)
endlocal

使用!而不是%进行延迟扩展,将会给你期望的结果。详见这里


还要记住,setlocal/endlocal实际上限制了它们内部更改的作用域,以确保它们不会泄漏出去。如果你想在endlocal之后使用count,你必须使用一个"技巧",这个技巧是通过你正在遇到的问题所提供的:

endlocal && set count=%count%

假设在内部作用域中,count 变成了 7。因为整个命令在执行之前都会被解释,所以它实际上变成了:

endlocal && set count=7

当代码被执行时,内部作用域随之关闭,将count还原至其初始值。但是,由于将count设置为七的操作发生在外部作用域中,因此可以泄漏所需的信息。

您可以将多个子命令串联起来,以泄漏尽可能多的信息:

endlocal && set count=%count% && set something_else=%something_else%

3
只使用 SETLOCAL ENABLEDELAYEDEXPANSION 而不包括 ENABLEEXTENSIONS 行不行? - Anthony Miller
@Mechaflash:可能吧,我从来没有尝试过。我总是在我的脚本顶部有那一行,因为我也使用其他东西。 - paxdiablo
是的,事实证明这是一个关于“enabledelayedexpansion”的含义以及其用途的重要学习经验。 - djangofan
就是这个了!感谢您解释!%的区别! - AndrewRalon

27

对于a从1到100,每次增加1:

在Windows命令行中。如果在批处理文件中运行,请使用%%a。

    for /L %a in (1,1,100) Do echo %a 

3
您的回答与问题无关。 - jeb
12
这就是我在搜索“Windows批处理计数循环”时寻找的答案。 - PeteB
1
这个回答恰好回答了标题中的问题。下次请学会更好地总结你的问题 ;) - rustyx
4
for /L %a in (1,1,100) Do echo %a for pseudo for a = 1 to 100 step 1 is a poor example. A better one would be for /L %a in (1,5,100) Do echo %a for pseudo for a = 1 to 100 step 5 because it clearly implies syntax for /L %a in (start,step,end) - Siddhant Rimal
这就是我在寻找的答案。我没有阅读问题,只看了主题和回复。这个回复恰好回答了问题。这是一个简单的解决方案,我很喜欢它。 - zappee
显示剩余3条评论

1
这是一个批处理文件,可以生成所有的10.x.x.x地址。
@echo off

SET /A X=0
SET /A Y=0
SET /A Z=0

:loop
SET /A X+=1
echo 10.%X%.%Y%.%Z%
IF "%X%" == "256" (
 GOTO end
 ) ELSE (
 GOTO loop2
 GOTO loop
 )


:loop2
SET /A Y+=1
echo 10.%X%.%Y%.%Z%
IF "%Y%" == "256" (
  SET /A Y=0
  GOTO loop
  ) ELSE (
   GOTO loop3
   GOTO loop2
 )


:loop3

SET /A Z+=1
echo 10.%X%.%Y%.%Z%
IF "%Z%" == "255" (
  SET /A Z=0
  GOTO loop2
 ) ELSE (
   GOTO loop3
 )

:end

您可以保存批处理文件并从命令行运行它。然后,您可以在命令行中执行“ip.bat> ip.csv”,它将生成一个IP地址的CSV文件。 - Steve Hull

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接