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?

17
demandé sur Mehrdad 2011-07-18 09:02:26

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
)
5
répondu jeb 2011-07-18 08:44:42

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.

4
répondu wimh 2017-05-23 12:10:13

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.

1
répondu Michel de Ruiter 2017-05-23 12:25:47

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
0
répondu Austin Powers 2015-04-12 23:43:59

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.

0
répondu John Hofmann 2016-12-19 08:44:30

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.

-1
répondu Tim 2011-07-18 05:43:58