Как разорвать внутренний цикл в пакетном скрипте с вложенным циклом - PullRequest
16 голосов
/ 17 января 2011

Моя цель - сравнивать два файла построчно и фиксировать изменения.Для этого я использую два вложенных цикла.Я застрял с торможением внутреннего цикла при некоторых условиях.

Я использую метку вне внутреннего цикла для ее разрыва, но не работаю.Это идет, чтобы маркировать и завершить внешний цикл также.

@ echo off
SETLOCAL EnableDelayedExpansion
for /F "skip=8 tokens=* delims=." %%a in (sample.txt) do (for /F "skip=8 tokens=* delims=." %%b in (test.txt) do (if %%a==%%b (goto :next) else ( echo %%a) 
)
: Next
echo out of inner loop
)

Кто-нибудь может помочь ....?

Ответы [ 3 ]

15 голосов
/ 17 января 2011

Goto: метка всегда разрывает все петли.

Но вы можете поместить свой внутренний цикл в отдельную функцию, тогда он сможет работать.

@echo off
SETLOCAL EnableDelayedExpansion
for /F "skip=8 tokens=* delims=." %%a in (sample.txt) do (
    call :myInnerLoop "%%a"
)

echo out of inner loop
)
goto :eof


:myInnerLoop
for /F "skip=8 tokens=* delims=." %%b in (test.txt) do (
    if "%~1"=="%%b" (
        goto :next
    ) else ( 
        echo %%a
    )
:next
goto :eof

Одно замечание: разрыв циклов FOR / L работает не так, как ожидалось, цикл for всегда отсчитывается до конца, но если вы нарушите его, выполнение внутреннего кода будет остановлено, но это может быть очень медленным.

@echo ON
FOR /L %%n IN (1,1,1000000) DO (
  echo %%n - count
  goto :break
)
:break

РЕДАКТИРОВАТЬ:

Подтверждение концепции

@echo off
SETLOCAL EnableDelayedExpansion
for %%a in (a b c) DO (
   echo Outer loop %%a
   call :inner %%a
)
goto :eof
:inner
for %%b in (U V W X Y Z) DO (
  if %%b==X (
    echo    break
    goto :break
  )
  echo    Inner loop    Outer=%1 Inner=%%b
)
:break
goto :eof

выход

Outer loop a
   Inner loop    Outer=a Inner=U
   Inner loop    Outer=a Inner=V
   Inner loop    Outer=a Inner=W
   break
Outer loop b
   Inner loop    Outer=b Inner=U
   Inner loop    Outer=b Inner=V
   Inner loop    Outer=b Inner=W
   break
Outer loop c
   Inner loop    Outer=c Inner=U
   Inner loop    Outer=c Inner=V
   Inner loop    Outer=c Inner=W
   break
3 голосов
/ 25 марта 2012

Даже если метка goto находится в цикле for, она также выходит из контекста цикла.Например,

@echo off
for %%d in (A B) do (
    echo %%d
    for %%f in ( 1 2 ) do (
        goto loop
        :loop
        echo %%d %%f
    )
)

Это распечатает A% d% f

1 голос
/ 17 января 2011

вам не нужно изобретать велосипед (если у вас есть выбор). Это только один из способов. Скачайте diffutils для Windows, и тогда вы можете просто сделать

diff sample.txt test.txt
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...