Sortir d'une boucle FOR dans un fichier batch?
pourquoi ce fichier batch ne sort-il jamais de la boucle?
For /L %%f In (1,1,1000000) Do @If Not Exist %%f Goto :EOF
ne devrait pas le Goto :EOF
sortir de la boucle?
Edit:
je suppose que j'aurais dû demander plus explicitement... comment puis-je sortir de la boucle?
6 réponses
Vous pouvez simplement utiliser echo on
et vous verrez que goto :eof
ou encore exit /b
ne fonctionne pas comme prévu.
le code à l'intérieur de la boucle n'est plus exécuté, mais la boucle est étendue pour tous les nombres jusqu'à la fin.
C'est pourquoi il est si lent.
la seule façon de sortir d'une boucle FOR /L semble être la variante de exit
comme L'exemple de Wimmel, mais ce n'est pas très rapide ni utile pour accéder aux résultats de la boucle.
cela indique 10 les expansions, mais aucune d'elles ne sera exécutée!--6-->
echo on
for /l %%n in (1,1,10) do (
goto :eof
echo %%n
)
basé sur Tim deuxième édition et cette page vous pourriez faire ceci:
@echo off
if "%1"=="loop" (
for /l %%f in (1,1,1000000) do (
echo %%f
if exist %%f exit
)
goto :eof
)
cmd /v:on /q /d /c "%0 loop"
echo done
Cette page suggère une façon d'utiliser un goto à l'intérieur d'une boucle, il semble que cela fonctionne, mais il faut un certain temps dans une grande boucle. Si intérieurement il termine la boucle avant que le goto est exécutée.
jebindiqué, le reste de la boucle est ignorée mais évalués, ce qui fait le FOR
solution trop lente à cet effet. Une alternative:
set F=1
:nextpart
if not exist "%F%" goto :EOF
echo %F%
set /a F=%F%+1
goto nextpart
Vous pourriez avoir besoin d'utiliser expansion retardée et call
sous-programmes lors de l'utilisation de ce dans les boucles.
Pour bien sortir d'une boucle for dans le DOS, juste goto étiquette;
Changer ceci:
For /L %%f In (1,1,1000000) Do If Not Exist %%f Goto :EOF
À:
For /L %%f In (1,1,1000000) Do If Not Exist %%f Goto:fileError
.. do something
.. then exit or do somethign else
:fileError
GOTO:EOF
mieux encore, ajoutez quelques rapports d'erreurs:
set filename=
For /L %%f In (1,1,1000000) Do(
set filename=%%f
If Not Exist %%f set tempGoto:fileError
)
.. do something
.. then exit or do somethign else
:fileError
echo file does not exist '%filename%'
GOTO:EOF
alors je me rends compte que c'est un peu ancien, mais après avoir cherché sur Google, je n'ai pas pu trouver une réponse qui me plaisait, alors j'ai trouvé ma propre solution pour briser une boucle FOR qui arrête immédiatement l'itération, et j'ai pensé que je la partagerais.
il nécessite que la boucle soit dans un fichier séparé, et exploite un bug dans la gestion des erreurs CMD pour planter immédiatement le traitement par lots du fichier de boucle lors de la redirection du STDOUT de DIR à STDIN.
MainFile.cmd
ECHO Simple test demonstrating loop breaking.
ECHO.
CMD /C %~dp0\LOOP.cmd
ECHO.
ECHO After LOOP
PAUSE
boucle.cmd
FOR /L %%A IN (1,1,10) DO (
ECHO %%A
IF %%A EQU 3 DIR >&0 2>NUL )
)
lors de l'exécution, cela produit la sortie suivante. Vous remarquerez que l'itération et l'exécution de la boucle s'arrêtent quand %a = 3.
:>MainFile.cmd
:>ECHO Simple test demonstrating loop breaking.
Simple test demonstrating loop breaking.
:>ECHO.
:>CMD /C Z:\LOOP.cmd
:>FOR /L %A IN (1 1 10) DO (
ECHO %A
IF %A EQU 3 DIR 1>&0 2>NUL
)
:>(
ECHO 1
IF 1 EQU 3 DIR 1>&0 2>NUL
)
1
:>(
ECHO 2
IF 2 EQU 3 DIR 1>&0 2>NUL
)
2
:>(
ECHO 3
IF 3 EQU 3 DIR 1>&0 2>NUL
)
3
:>ECHO.
:>ECHO After LOOP
After LOOP
:>PAUSE
Press any key to continue . . .
si vous avez besoin de préserver une seule variable de la boucle, avoir L'écho boucle le résultat de la variable, et utiliser une boucle FOR /F dans le fichier principal.cmd pour analyser la sortie de la boucle.fichier cmd.
exemple (utilisant la même boucle.fichier cmd en tant que ci-dessus):
MainFile.cmd
@ECHO OFF
ECHO.
ECHO Simple test demonstrating loop breaking.
ECHO.
FOR /F "delims=" %%L IN ('CMD /C %~dp0\LOOP.cmd') DO SET VARIABLE=%%L
ECHO After LOOP
ECHO.
ECHO %VARIABLE%
ECHO.
PAUSE
Sortie:
:>MainFile.cmd
Simple test demonstrating loop breaking.
After LOOP
3
Press any key to continue . . .
si vous avez besoin de préserver plusieurs variables, vous aurez besoin de les rediriger vers des fichiers temporaires comme indiqué ci-dessous.
MainFile.cmd
@ECHO OFF
ECHO.
ECHO Simple test demonstrating loop breaking.
ECHO.
CMD /C %~dp0\LOOP.cmd
ECHO After LOOP
ECHO.
SET /P VARIABLE1=<%TEMP%
SET /P VARIABLE2=<%TEMP%
ECHO %VARIABLE1%
ECHO %VARIABLE2%
ECHO.
PAUSE
boucle.cmd
@ECHO OFF
FOR /L %%A IN (1,1,10) DO (
IF %%A EQU 1 ECHO ONE >%TEMP%
IF %%A EQU 2 ECHO TWO >%TEMP%
IF %%A EQU 3 DIR >&0 2>NUL
)
Sortie:
:>MainFile.cmd
Simple test demonstrating loop breaking.
After LOOP
ONE
TWO
Press any key to continue . . .
j'espère que d'autres trouveront cela utile pour briser des boucles qui autrement prendraient trop de temps à sortir en raison de l'itération continue.
a fait un peu de recherche sur ce, il semble que vous faites une boucle de 1 à 2147483647, par incréments de 1.
(1, 1, 2147483647): Le premier nombre est le nombre de départ, le prochain numéro de l'étape, et le dernier numéro est à la fin du numéro.
Edité Pour Ajouter
il semble que la boucle s'exécute jusqu'à son achèvement, quelles que soient les conditions d'essai. J'ai testé
FOR /L %%F IN (1, 1, 5) DO SET %%F=6
et il a couru très vite.
Deuxième Edit
FOR /L %%F IN (1, 1, 2147483647) DO @IF NOT EXIST %%F EXIT
cependant, cela fermera aussi la fenêtre d'invite DOS.