20

MY goal is to compare two files line by line and capture the changes. For that i am using two nested loops. I am stuck with braking the inner loop on some condition.

I am using label outside the inner loop for break it, but not working. It goes to label and terminate outer loop also.

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

Anyone can help....?

Bali C
  • 30,582
  • 35
  • 123
  • 152
Rock with IT
  • 361
  • 3
  • 5
  • 14

3 Answers3

17

A goto :label always breaks all loops.

But you can put your inner loop in a separated function, then it could work.

@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

One remark, breaking of FOR /L loops does not work as expected, the for-loop always count to the end, but if you break it, the execution of the inner code is stopped, but it could be really slow.

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

EDIT:

Proof of concept

@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

Output

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
jeb
  • 78,592
  • 17
  • 171
  • 225
  • This is also doing the same. if condition is true, it will goto label next and then both loops will end. My purpose is, after reaching on label next it should again go to 1st loop and check the same for next value. In current case it will check for only 1st value. – Rock with IT Jan 17 '11 at 10:57
  • It seems as if the OP wanted that on breaking at, for example, `X` in the inner loop it would move to the next value in the outer loop and sort of resume the inner loop from `X`. I hope the OP will correct me if I'm wrong. – Andriy M Feb 01 '11 at 09:06
  • this also works if the inner loop is in separated file. – npocmaka Nov 06 '14 at 23:02
3

Even if the goto label is in the for loop, it also goes out the loop context. Such as

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

This will print out A %d %f

1

you do not have to reinvent the wheel (if you have a choice). This is just one way. Download diffutils for windows and then you can just do

diff sample.txt test.txt
ghostdog74
  • 327,991
  • 56
  • 259
  • 343