Boucle de script par lots

275

J'ai besoin d'exécuter une commande 100-200 fois, et jusqu'à présent, mes recherches indiquent que je devrais soit copier / coller 100 copies de cette commande, OU utiliser une forboucle, mais la forboucle attend une liste d'éléments, donc j'aurais besoin 200 fichiers sur lesquels opérer, ou une liste de 200 éléments, ce qui ne va pas.

Je préfère ne pas avoir à écrire un programme C et à parcourir la longueur de la documentation de 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 pas non plus une option.

Donc, étant donné une commande, acomment pourrais-je l'exécuter plusieurs Nfois via un script batch?

Remarque: je ne veux pas d'une boucle infinie

Par exemple, voici à quoi cela ressemblerait en Javascript:

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

À quoi cela ressemblerait-il dans un script batch exécuté sur Windows?

Tom J Nowell
la source

Réponses:

524

for /l est votre ami:

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

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

Utilisez deux %s si c'est dans un fichier batch

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

(qui est une des choses que je déteste vraiment à propos des scripts 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é:
/lindique que la forcommande fonctionnera de manière numérique, plutôt que d'opérer sur un ensemble de fichiers,
%xc'est la variable boucles
(valeur de départ, incrément de valeur, condition de fin [inclus]))

Jon
la source
2
Cela dépend de la façon dont nous devons littéralement prendre la référence "DOS". La dernière version de MS-DOS, 7.1, remonte à 1997 et AFAIK n'a pas ces extensions. Les shells de commande livrés avec Windows, d'autre part, bien sûr.
Carl Smotricz
8
@Imray %xest la variable de boucle, /l(pas \l) signifie que la commande for fonctionnera de manière numérique, plutôt que d'opérer sur un ensemble de fichiers.
Jon
19
En exécutant, for /l %x in (1, 1, 100) do echo %xj'obtiens "x non attendu".
LaBracca
2
@ user193655 lisez le reste de la réponse, vous devez doubler le% s si vous faites cela dans un fichier batch.
Jon
7
% x dans la dernière boucle doit être %% x.
wildpointercs
63

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 n'interprète la variable qu'une seule fois (avant qu'elle n'entre dans la boucle) et non à chaque fois que le programme boucle.

Olivier Faucheux
la source
19
Merci d'avoir posté ceci - je sais que ce n'est pas ce que le PO demandait, mais c'est ce que je cherchais quand je me suis retrouvé ici.
BrainSlugs83
24

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 "Bonjour tout le monde!" 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 . . .
FluorescentGreen5
la source
c'est le seul code de boucle que j'ai pu utiliser sur mon PC win7. Tous les autres trouvés par google ne fonctionnent pas.
LaBracca
2
Dans votre exemple, j'ajouterais set /p loopcount="How many loops? "pour que vous puissiez l'exécuter avec une entrée utilisateur. C'est plus pratique.
1934286
8

Vous pouvez également essayer ceci au lieu d'une forboucle:

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.

BlazeLP
la source
1
Ceci est fondamentalement identique à la réponse de Marcus Culver . Veuillez ne pas poster de réponses qui n'ajoutent rien de nouveau. Je vous remercie!
Fabio dit Réintégrer Monica
Ups sry n'a pas vu ça, il a juste volé et l'a juste vu pour les boucles ... Je suis désolé alors :)
BlazeLP
6

Ou vous pouvez décrémenter / incrémenter une variable du nombre de fois que vous voulez boucler:

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 /Lest l'autoroute et c'est la ruelle qui prend plus de temps, mais elle arrive à la même destination.

Mechaflash
la source
5

Vous pouvez faire quelque chose dans le sens 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
Marcus Culver
la source
2

Vous pouvez le faire sans forinstruction ^. ^:

@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. Faites juste un test. : P

zask
la source
1
vous n'avez pas besoin d'une expansion retardée ici.
Stephan
2

Moyen très basique d'implémenter le bouclage dans la programmation 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
)
Rakesh Chaudhari
la source
1

DOS n'offre 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 chiffrefor boucle , 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 quitter la boucle, comparez la valeur de X avec une chaîne de 100 (ou 200) @signes.

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

Carl Smotricz
la source
1
L' /aoption de la SETcommande évaluera une expression numérique pour la valeur du côté droit. Voir la doucmentation pour SET . Il n'est pas nécessaire de faire l'astuce de concaténation.
Adam Porad
2
pour DOS, il est neccessary, comme il n'y a pas set /adans le DOS. Heureusement, la question est pour cmd... (au moment de cette réponse, le titre de la question était "Boucle de script batch DOS"
Stephan
0

Je ne sais 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'à ce qu'elle atteigne 100 où le programme sort ensuite qu'il a terminé son exécution. Encore une fois, je ne sais pas si cela a été soumis ou quelque chose comme ça, mais je pense que c'est peut-être le plus compact.

Josh Girouard
la source
0

J'utilise ça. 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
Jordan B
la source
0

La réponse dépend vraiment de votre familiarité avec le batch, si vous n'êtes pas aussi expérimenté, je 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 le batch, je recommanderais que le plus pratique for /l %loop in (1, 1, 10) do echo %loopsoit 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]
Dr Hugh Jarse
la source
0

Voici un modèle de script que j'utiliserai.

@echo off
goto Loop

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

exit

Ce que cela fait, c'est quand il démarre, il éteint l'écho puis après cela, il exécute la "boucle", mais à cet endroit, il continue à "boucle" (j'espère que cela aide.)

Se terrer
la source
0

une boucle parfaitement parfaite

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

vous pouvez le modifier en remplaçant le 10 de la ligne 5 par un nombre quelconque pour représenter le nombre de fois que vous voulez qu'il boucle.

guest257351
la source
-2

(MODIFIÉ) Je l'ai fait pour que ça s'arrête après 100 fois

@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

Cela générera 4 nombres aléatoires à chaque seconde 100 secondes. Sortez le "timeout 1 / nobreak> nul" pour le faire aller très vite.

Manny
la source
3
la question était "100 - 200 fois", pas "boucle sans fin".
Stephan
-2

Probablement utiliser goto like

@echo off
:Whatever
echo hello world
pause
echo TEST
goto Whatever

Cela fait une boucle inf (infinie).

Lamdenny5ONROBLOX
la source
eh bien, infiniteest un peu plus grand que la demande 100-200 times, donc cela ne répond pas à la question.
Stephan
En effet, je voulais pouvoir boucler un nombre défini de fois, donc je n'aurais pas à copier-coller une commande encore et encore
Tom J Nowell
-2

J'ai 2 réponses Méthodes 1: Insérer Javascript dans le lot

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

:: batch portion

@ECHO OFF

cscript /e:jscript "%~f0"


:: JScript portion */

Input Javascript here

(Je ne connais pas grand chose à JavaScript)

Méthode 2: boucle en lot

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

(Merci FluorescentGreen5)

Cocos Nucifera
la source
1
Nous apprécions votre tentative de contribuer, mais répéter mot à mot une réponse vieille de cinq ans n'aide pas beaucoup et ajoute simplement du bruit.
Stephan