web-dev-qa-db-fra.com

Boucle de script batch

J'ai besoin d'exécuter une commande 100 à 200 fois, et jusqu'à présent, ma recherche indique que je devrais soit copier/coller 100 copies de cette commande, OR utiliser une boucle for, mais le La boucle for attend une liste d'éléments. Par conséquent, il me faudrait 200 fichiers sur lesquels opérer, ou une liste de 200 éléments, afin d'éviter le point.

Je préférerais ne pas avoir à écrire un programme C et expliquer en détail la raison pour laquelle j'ai dû écrire un autre programme pour exécuter mon programme à des fins de test. La modification de mon programme lui-même n'est également pas une option.

Donc, étant donné une commande, a, comment puis-je l'exécuter N fois via un script batch?

248
Tom J Nowell

for /l est votre ami:

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

Commence à 1, pas à pas et termine à 100.

Utilisez deux %s s'il s'agit d'un fichier de commandes.

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

(ce qui est une des choses que je déteste vraiment à propos du scripting Windows)

Si vous avez plusieurs commandes pour chaque itération de la boucle, procédez comme suit:

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

ou dans un fichier batch

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

Clé:
/l indique que la commande for fonctionnera sous forme numérique plutôt que sur un ensemble de fichiers.
%x est la variable de boucles
(valeur de départ, incrément de valeur, condition de fin [incluse])

482
Jon

Et pour itérer sur les fichiers d'un répertoire:

@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!
)

Vous devez utiliser "enableDelayedExpansion" et! FILENAME! au lieu de $ FILENAME $. Dans le second cas, DOS interprétera la variable une seule fois (avant qu’elle n’entre dans la boucle) et non à chaque boucle du programme.

61
Olivier Faucheux

Modèle pour une boucle simple mais comptée:

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

Exemple: Dites "Hello World!" 5 fois:

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

Cet exemple affichera:

Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Press any key to continue . . .
19
FluorescentGreen5

Vous pouvez aussi essayer ceci à la place d'une boucle for:

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

C'est assez petit et c'est ce que j'utilise tout le temps.

6
BlazeLP

Ou vous pouvez décrémenter/incrémenter une variable du nombre de fois que vous souhaitez faire une boucle:

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

Évidemment, utiliser FOR /L est l’autoroute et c’est la rue arrière qui prend plus de temps, mais elle se rend à la même destination.

6
Mechaflash

Vous pouvez faire quelque chose avec l’effet suivant en évitant la boucle FOR.

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

Vous pouvez faire cela sans une instruction for. ^: ^:

@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

Il a une compréhension de base. Juste lui faire un test. : P

2
zask

DOS ne propose pas de mécanismes très élégants pour cela, mais je pense que vous pouvez toujours coder une boucle pour 100 ou 200 itérations avec un effort raisonnable. Bien qu'il n'y ait pas de boucle numérique for, vous pouvez utiliser une chaîne de caractères comme "variable de boucle".

Codez la boucle en utilisant GOTO, et pour chaque itération, utilisez SET X=%X%@ pour ajouter un autre signe @ à une variable d’environnement X; et pour sortir de la boucle, comparez la valeur de X avec une chaîne de signes 100 (ou 200) @.

Je n'ai jamais dit que c'était élégant, mais ça devrait marcher!

1
Carl Smotricz

Moyen très basique d'implémenter la programmation en boucle dans cmd à l'aide d'étiquettes

@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
)
1
Rakesh Chaudhari

La réponse dépend vraiment de votre niveau de familiarisation avec batch. Si vous n’êtes pas aussi expérimenté, je vous recommanderais d’incrémenter une variable de boucle:

@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

Mais si vous êtes plus expérimenté avec batch, je recommanderais le plus pratique for /l %loop in (1, 1, 10) do echo %loop est le meilleur choix.

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

Utiliser seq dans la boucle

for i in `seq 1 100`
do 
   echo $i
done
0
Dennis Djan

Je l'utilise. C'est à peu près la même chose que les autres, mais c'est juste une autre façon de l'écrire.

@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
0
Jordan B

Vous ne savez pas si une réponse comme celle-ci a déjà été soumise, mais vous pouvez essayer quelque chose comme ceci:

@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

La variable% var% augmentera de un jusqu'à atteindre 100 où le programme indique ensuite qu'il a fini de s'exécuter. Encore une fois, je ne sais pas si cela a été soumis ou quelque chose du genre, mais je pense que c'est peut-être le plus compact.

0
Josh Girouard