45

Can anyone explain this? I am able to count in a loop using the Windows command prompt, using this method:

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

But this method does not work (it prints out "1" for each line in the file). It acts like the variable is out of scope:

SET /A COUNT=1
FOR /F "tokens=*" %%A IN (config.properties) DO (
  SET /A COUNT+=1
  ECHO %COUNT%
)
Ross Ridge
  • 38,414
  • 7
  • 81
  • 112
djangofan
  • 28,471
  • 61
  • 196
  • 289

3 Answers3

77

It's not working because the entire for loop (from the for to the final closing parenthesis, including the commands between those) is being evaluated when it's encountered, before it begins executing.

In other words, %count% is replaced with its value 1 before running the loop.

What you need is something like:

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

Delayed expansion using ! instead of % will give you the expected behaviour. See also here.


Also keep in mind that setlocal/endlocal actually limit scope of things changed inside so that they don't leak out. If you want to use count after the endlocal, you have to use a "trick" made possible by the very problem you're having:

endlocal && set count=%count%

Let's say count has become 7 within the inner scope. Because the entire command is interpreted before execution, it effectively becomes:

endlocal && set count=7

Then, when it's executed, the inner scope is closed off, returning count to it's original value. But, since the setting of count to seven happens in the outer scope, it's effectively leaking the information you need.

You can string together multiple sub-commands to leak as much information as you need:

endlocal && set count=%count% && set something_else=%something_else%
Community
  • 1
  • 1
paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
27

for a = 1 to 100 step 1

Command line in Windows . Please use %%a if running in Batch file.

    for /L %a in (1,1,100) Do echo %a 
sujith
  • 297
  • 3
  • 2
  • 3
    Your answer is not related to the question – jeb Aug 10 '16 at 23:18
  • 11
    this is the answer I was looking for when I searched for "counted for loop windows batch" – PeteB Dec 04 '16 at 21:34
  • Me too -- this worked perfectly for me, and it's simple and elegant. – dbeachy1 Dec 05 '16 at 02:00
  • 1
    This answers exactly the question in the title. Next time, learn to summarize your question better ;) – rustyx Feb 27 '17 at 10:03
  • 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 Nov 29 '17 at 04:51
  • This is the answer I was looking for. I have not read the question, only the topic and the responses. This response exactly answers the question. It is a simple solution, I like it. – zappee Aug 23 '22 at 14:57
  • I am more a Unix Bash guy than Windows Batch. Interesting why this `%%a` only accepts one character, for example, `%%index` does not work. Windows makes me crazy... – zappee Aug 23 '22 at 15:01
  • This is what I wanted... I just wanted a Windows version of `for number in {1..100..1}; do echo $number; done` – Epic Programmer Sep 01 '22 at 15:59
1

Here is a batch file that generates all 10.x.x.x addresses

@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
Steve Hull
  • 19
  • 1
  • You can save the batch file and run it from the command line. You can then do a "ip.bat> ip.csv" at the command line and it will generate a csv of IP addresses. – Steve Hull Jun 03 '19 at 14:54