291

I need to execute a command 100-200 times, and so far my research indicates that I would either have to copy/paste 100 copies of this command, OR use a for loop, but the for loop expects a list of items, hence I would need 200 files to operate on, or a list of 200 items, defeating the point.

I would rather not have to write a C program and go through the length of documenting why I had to write another program to execute my program for test purposes. Modification of my program itself is also not an option.

So, given a command, a, how would I execute it N times via a batch script?

Note: I don't want an infinite loop

For example, here is what it would look like in Javascript:

var i;
for (i = 0; i < 100; i++) {
  console.log( i );
} 

What would it look like in a batch script running on Windows?

Tom J Nowell
  • 8,415
  • 16
  • 57
  • 88

16 Answers16

561

for /l is your friend:

for /l %x in (1, 1, 100) do echo %x

Starts at 1, steps by one, and finishes at 100.

Use two %s if it's in a batch file

for /l %%x in (1, 1, 100) do echo %%x

(which is one of the things I really really hate about windows scripting)

If you have multiple commands for each iteration of the loop, do this:

for /l %x in (1, 1, 100) do (
   echo %x
   copy %x.txt z:\whatever\etc
)

or in a batch file

for /l %%x in (1, 1, 100) do (
   echo %%x
   copy %%x.txt z:\whatever\etc
)

Key:
/l denotes that the for command will operate in a numerical fashion, rather than operating on a set of files
%x is the loops variable
(starting value, increment of value, end condition[inclusive] )

Jed Fox
  • 2,962
  • 4
  • 27
  • 36
Jon
  • 14,742
  • 8
  • 49
  • 58
  • Much better than my solution, provided we're talking about a reasonably modern DOS. – Carl Smotricz Apr 07 '10 at 11:02
  • 2
    That depends on how literally we are to take the "DOS" reference. The latest version of MS-DOS, 7.1, dates back to 1997 and AFAIK doesn't have these extensions. The command shells delivered with Windows, on the other hand, of course do. – Carl Smotricz Apr 07 '10 at 11:55
  • Im using this to run a game repeatedly with a personal project of mine loaded, along with some statistics generation code. I should think anybody who cant run with a NT or later version of windows doesnt stand a chance at executing much else these days – Tom J Nowell Apr 09 '10 at 02:53
  • 8
    @Imray `%x` is the loop variable, `/l` (not `\l`) means that the for command will operate in a numerical fashion, rather than operating on a set of files. – Jon Jan 14 '14 at 23:20
  • 19
    By running `for /l %x in (1, 1, 100) do echo %x` i get "x not expected". – LaBracca Mar 23 '15 at 14:58
  • 2
    @user193655 read the rest of the answer, you need to double the %s if you're doing this in a batch file. – Jon Mar 23 '15 at 23:47
  • 1
    @Jon, Why is it that two `%` is required if using a batch file? – Pacerier May 22 '15 at 09:43
  • read output of "help for" in your favorite dos/win shell. This will tell all. (And if it doesn't, "for" is not present.) – Christian Gosch Jul 31 '15 at 07:13
  • If you want to run multiple lines of code and one of those lines contains parenthesis () then you may run into issues and need to revert to a loop method. – Edward Comeau Feb 07 '17 at 11:47
  • by running above command, it is giving following error message on the console, "x was unexpected at this time" – Rakesh Chaudhari Nov 04 '17 at 10:07
  • 1
    **%** has a special meaning in batch files. I assume **%%** is needed to escape the character while processing the batch file [see this answer](https://stackoverflow.com/a/382312/773334] – JACH Feb 20 '18 at 17:13
66

And to iterate on the files of a directory:

@echo off 
setlocal enableDelayedExpansion 

set MYDIR=C:\something
for /F %%x in ('dir /B/D %MYDIR%') do (
  set FILENAME=%MYDIR%\%%x\log\IL_ERROR.log
  echo ===========================  Search in !FILENAME! ===========================
  c:\utils\grep motiv !FILENAME!
)

You must use "enableDelayedExpansion" and !FILENAME! instead of $FILENAME$. In the second case, DOS will interpret the variable only once (before it enters the loop) and not each time the program loops.

Olivier Faucheux
  • 2,242
  • 3
  • 27
  • 33
  • 21
    Thanks for posting this -- I know it's not what the OP was asking, but it's what I was searching for when I ended up here. – BrainSlugs83 Jun 05 '13 at 20:42
29

Template for a simple but counted loop:

set loopcount=[Number of times]
:loop
[Commands you want to repeat]
set /a loopcount=loopcount-1
if %loopcount%==0 goto exitloop
goto loop
:exitloop

Example: Say "Hello World!" 5 times:

@echo off
set loopcount=5
:loop
echo Hello World!
set /a loopcount=loopcount-1
if %loopcount%==0 goto exitloop
goto loop
:exitloop
pause

This example will output:

Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Press any key to continue . . .
  • this is the only loop code i was able to use on my win7 pc. All the others found by googleing do not work. – LaBracca Mar 23 '15 at 14:56
  • 2
    In your example, I would add `set /p loopcount="How many loops? "` so that you can run it with user input. It's more practical. – 1934286 Feb 08 '17 at 00:40
8

You could also try this instead of a for loop:

set count=0
:loop
set /a count=%count%+1
(Commands here)
if %count% neq 100 goto loop
(Commands after loop)

It's quite small and it's what I use all the time.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
BlazeLP
  • 117
  • 1
  • 7
6

You could do something to the following effect avoiding the FOR loop.

set counter=0
:loop
echo "input commands here"
SET /A counter=%counter%+1
if %counter% GTR 200
(GOTO exit) else (GOTO loop)
:exit
exit
Marcus Culver
  • 305
  • 1
  • 4
  • 8
6

Or you can decrement/increment a variable by the number of times you want to loop:

SETLOCAL ENABLEDELAYEDEXPANSION
SET counter=200
:Beginning
IF %counter% NEQ 0 (
echo %x
copy %x.txt z:\whatever\etc
SET /A counter=%counter%-1
GOTO Beginning
) ELSE (
ENDLOCAL
SET counter=
GOTO:eof

Obviously, using FOR /L is the highway and this is the backstreet that takes longer, but it gets to the same destination.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Anthony Miller
  • 12,722
  • 27
  • 65
  • 96
2

You can do this without a for statement ^.^:

@echo off
:SPINNER
SET COUNTP1=1

:1
CLS
 :: YOUR COMMAND GOES HERE
IF !COUNTP1! EQU 200 goto 2

SET COUNTP1=1
) ELSE (
SET /A COUNTP1+=1
)
goto 1

:2
:: COMMAND HAS FINISHED RUNNING 200 TIMES

It has basic understanding. Just give it a test. :P

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
zask
  • 181
  • 1
  • 5
2

Very basic way to implement looping in cmd programming using labels

@echo off
SET /A "index=1"
SET /A "count=5"
:while
if %index% leq %count% (
   echo The value of index is %index%
   SET /A "index=index + 1"
   goto :while
)
Rakesh Chaudhari
  • 2,420
  • 1
  • 21
  • 22
1

DOS doesn't offer very elegant mechanisms for this, but I think you can still code a loop for 100 or 200 iterations with reasonable effort. While there's not a numeric for loop, you can use a character string as a "loop variable."

Code the loop using GOTO, and for each iteration use SET X=%X%@ to add yet another @ sign to an environment variable X; and to exit the loop, compare the value of X with a string of 100 (or 200) @ signs.

I never said this was elegant, but it should work!

Carl Smotricz
  • 62,722
  • 17
  • 119
  • 161
  • 1
    The `/a` option of the `SET` command will evaluate a numerical expression for the right side value. See the doucmentation for [SET](http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/set.mspx?mfr=true). It is not necessary to do the concatenation trick. – Adam Porad Sep 13 '13 at 15:16
  • 2
    for DOS, it *is* neccessary, as there is no `set /a` in DOS. Luckily the qeustion is for `cmd`... (at the time of this answer, the question title was "DOS batch script loop" – Stephan Jul 08 '16 at 14:25
0

Not sure if an answer like this has already been submitted yet, but you could try something like this:

@echo off
:start
set /a var+=1
if %var% EQU 100 goto end
:: Code you want to run goes here
goto start

:end
echo var has reached %var%.
pause
exit

The variable %var% will increase by one until it reaches 100 where the program then outputs that it has finished executing. Again, not sure if this has been submitted or something like it, but I think it may be the most compact.

Josh Girouard
  • 71
  • 1
  • 5
0

I use this. It is just about the same thing as the others, but it is just another way to write it.

@ECHO off
set count=0
:Loop
if %count%==[how many times to loop] goto end
::[Commands to execute here]
set count=%count%+1
goto Loop
:end
Jordan B
  • 11
  • 1
0

The answer really depends on how familiar you are with batch, if you are not so experienced, I would recommend incrementing a loop variable:

@echo off
set /a loop=1
:repeat
echo Hello World!
set /a loop=%loop%+1
if %loop%==<no. of times to repeat> (
goto escapedfromrepeat
)
goto repeat
:escapedfromrepeat
echo You have come out of the loop
pause

But if you are more experienced with batch, I would recommend the more practical for /l %loop in (1, 1, 10) do echo %loop is the better choice.

             (start at 1, go up in 1's, end at 10)
for /l %[your choice] (start, step, end) do [command of your choice]
0

Here is a template script I will use.

@echo off
goto Loop

:Loop
<EXTRA SCRIPTING HERE!!!!>
goto Loop

exit

What this does is when it starts it turns off echo then after that it runs the "Loop" but in that place it keeps going to "Loop" (I hope this helps.)

Doggo
  • 11
  • 6
0

a completely flawless loop

set num=0
:loop
:: insert code
set num=%num%+1
if %num% neq 10 goto loop
::insert after code code

you can edit it by changing the 10 in line 5 to any number to represent how many time you want it to loop.

-3

(EDITED) I made it so it stops after 100 times

@echo off
goto actual
set /a loopcount=0
:actual
set /a loopcount=%loopcount% + 1
echo %random% %random% %random% %random%
timeout 1 /nobreak>nul
if %loopcount%== 100 goto stop
goto actual
:stop
exit

This will generate 4 random numbers ever 1 second 100 times. Take out the "timeout 1 /nobreak>nul" to make it go super fast.

Manny
  • 7
  • 1
-3

I have 2 answers Methods 1: Insert Javascript into Batch

@if (@a==@b) @end /*

:: batch portion

@ECHO OFF

cscript /e:jscript "%~f0"


:: JScript portion */

Input Javascript here

( I don't know much about JavaScript )

Method 2: Loop in Batch

   @echo off
    set loopcount=5
    :loop
    echo Hello World!
    set /a loopcount=loopcount-1
    if %loopcount%==0 goto exitloop
    goto loop
    :exitloop
    pause

(Thanks FluorescentGreen5)

  • 2
    We appreciate your attempt to contribute, but repeating a five year old answer verbatim doesn't help much and just adds noise. – Stephan May 05 '20 at 10:01