Exit FOR loop prematurely?

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
miskox
Posts: 555
Joined: 28 Jun 2010 03:46

Exit FOR loop prematurely?

#1 Post by miskox » 16 Apr 2012 05:08

Hi all,

is it possible to exit FOR loop prematurely?

Some info:

Let's say I have a file abc.txt with 100 records.

I do this:

Code: Select all

for /f "tokens=1 skip=10 delims=" %%i in (abc.txt) do call :DOSOMETHING %%i
:0
echo Continue here...
for /f "tokens=1 skip=30 delims=" %%i in (abc.txt) do call :DOSOMETHING %%i
for /f "tokens=1 skip=50 delims=" %%i in (abc.txt) do call :DOSOMETHING %%i
goto :EOF

:DOSOMETHING
echo Something is done here. And when I get to record 20 (for example) I
echo want to exit this FOR loop and want to continue with echo Continue here
echo (added label :0 just to know exactly what I mean).
echo.
echo To be more specific: let's say I have 3 FOR loops. Each would start lower
echo in the same file (in reality there are 50000+ records and this is very time
echo consuming).
goto :EOF


I have records I need to process somewhere in the middle of a file so in this way I don't have to read the rest of the file (and not to waste time).

Thanks,
Saso

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Exit FOR loop prematurely?

#2 Post by foxidrive » 16 Apr 2012 05:38

Code: Select all

for /f "tokens=1 skip=10 delims=" %%a in (abc.txt) do (
if /i "%%a"=="exact text" goto :next
call :DOSOMETHING %%a
)
:next
echo Continue here....

miskox
Posts: 555
Joined: 28 Jun 2010 03:46

Re: Exit FOR loop prematurely?

#3 Post by miskox » 16 Apr 2012 05:47

Yes, of course. GOTO will do the trick... (means more labels but who cares).

Thanks,
Saso

miskox
Posts: 555
Joined: 28 Jun 2010 03:46

Re: Exit FOR loop prematurely?

#4 Post by miskox » 17 Apr 2012 02:38

Ok, I did some testing. Here are my results:

First we have a file a.a:

Code: Select all

Record_01
Record_02
Record_03
Record_04
Record_05
Record_06
Record_07
Record_08
Record_09
Record_10
Record_11
Record_12
Record_13
Record_14
Record_15
Record_16
Record_17
Record_18
Record_19
Record_20
Record_21
Record_22
Record_23
Record_24
Record_25
Record_26
Record_27
Record_28
Record_29
Record_30
Record_31
Record_32
Record_33
Record_34
Record_35
Record_36
Record_37
Record_38
Record_39
Record_40


Then we have a.cmd:

Code: Select all

@echo off
set /a cnt=0
set  ctrl=1
for /f "tokens=1 skip=10 delims=" %%m in (a.a) do call :DOSOMETHING %%m
:DOSOMETHING1
set /a cnt=0
set ctrl=2
for /f "tokens=1 skip=20 delims=" %%m in (a.a) do call :DOSOMETHING %%m
:DOSOMETHING2
set /a cnt=0
set ctrl=3
for /f "tokens=1 skip=30 delims=" %%m in (a.a) do call :DOSOMETHING %%m
:END
echo HERE
REM only exit really stops the program - but this is not what I want.
goto :EOF
exit /b
exit

:DOSOMETHING
set /a cnt=cnt + 1
echo %ctrl% %1
if %cnt%==5 if %ctrl%==1 goto :DOSOMETHING1
if %cnt%==5 if %ctrl%==2 goto :DOSOMETHING2
if %cnt%==5 if %ctrl%==3 goto :END
goto :EOF



Result should be like this:

Code: Select all

1 Record_11
1 Record_12
1 Record_13
1 Record_14
1 Record_15
2 Record_21
2 Record_22
2 Record_23
2 Record_24
2 Record_25
3 Record_31
3 Record_32
3 Record_33
3 Record_34
3 Record_35
HERE


but it is not. Program still reads input file and adds lots of output (see below):

As you can see the program should ECHO 5 lines each time and then echo HERE and should stop there.

So, the question is: why GOTO :EOF does not work? Not even EXIT /B. Only EXIT terminates the program.

I even tried with %%m, %%n, %%o (if there is an internal context that might interfere).

Any ideas?
Thanks,
Saso
Actual output (complete):

Code: Select all

1 Record_11
1 Record_12
1 Record_13
1 Record_14
1 Record_15
2 Record_21
2 Record_22
2 Record_23
2 Record_24
2 Record_25
3 Record_31
3 Record_32
3 Record_33
3 Record_34
3 Record_35
HERE
3 Record_36
3 Record_37
3 Record_38
3 Record_39
3 Record_40
HERE
3 Record_26
3 Record_27
3 Record_28
3 Record_29
3 Record_30
3 Record_31
3 Record_32
3 Record_33
3 Record_34
3 Record_35
3 Record_36
3 Record_37
3 Record_38
3 Record_39
3 Record_40
3 Record_31
3 Record_32
3 Record_33
3 Record_34
3 Record_35
HERE
3 Record_36
3 Record_37
3 Record_38
3 Record_39
3 Record_40
HERE
3 Record_16
3 Record_17
3 Record_18
3 Record_19
3 Record_20
3 Record_21
3 Record_22
3 Record_23
3 Record_24
3 Record_25
3 Record_26
3 Record_27
3 Record_28
3 Record_29
3 Record_30
3 Record_31
3 Record_32
3 Record_33
3 Record_34
3 Record_35
3 Record_36
3 Record_37
3 Record_38
3 Record_39
3 Record_40
2 Record_21
2 Record_22
2 Record_23
2 Record_24
2 Record_25
3 Record_31
3 Record_32
3 Record_33
3 Record_34
3 Record_35
HERE
3 Record_36
3 Record_37
3 Record_38
3 Record_39
3 Record_40
HERE
3 Record_26
3 Record_27
3 Record_28
3 Record_29
3 Record_30
3 Record_31
3 Record_32
3 Record_33
3 Record_34
3 Record_35
3 Record_36
3 Record_37
3 Record_38
3 Record_39
3 Record_40
3 Record_31
3 Record_32
3 Record_33
3 Record_34
3 Record_35
HERE
3 Record_36
3 Record_37
3 Record_38
3 Record_39
3 Record_40
HERE

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Exit FOR loop prematurely?

#5 Post by foxidrive » 17 Apr 2012 04:40

Code: Select all

@echo off
setlocal enabledelayedexpansion
set c=0
for /f "tokens=1 skip=10 delims=" %%m in (a.a) do (
set /a c=c+1
call :DOSOMETHING %%m !c!
if !c! EQU 5 goto :DOSOMETHING1
)
:DOSOMETHING1
set c=0
for /f "tokens=1 skip=20 delims=" %%m in (a.a) do (
set /a c=c+1
call :DOSOMETHING %%m !c!
if !c! EQU 5 goto :DOSOMETHING2
)
:DOSOMETHING2
set c=0
for /f "tokens=1 skip=30 delims=" %%m in (a.a) do (
set /a c=c+1
call :DOSOMETHING %%m !c!
if !c! EQU 5 goto :DOSOMETHING3
)
:DOSOMETHING3
echo HERE
pause
goto :EOF

:DOSOMETHING
echo %2 = %1

miskox
Posts: 555
Joined: 28 Jun 2010 03:46

Re: Exit FOR loop prematurely?

#6 Post by miskox » 17 Apr 2012 09:54

Thank you.

I modified your solution to meet my needs. Now it works. I set a flag in a subroutine and I then check for this flag in a FOR loop (within () ) - though I would prefer a solution without this.

Still remains: why my original script does not work?

Thank you again. Now I managed to save even some more time (I would say 30%) with my HTML parser.

Saso

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Exit FOR loop prematurely?

#7 Post by foxidrive » 17 Apr 2012 10:20

miskox wrote:Still remains: why my original script does not work?


It's because you are doing it from a CALLed subroutine and the return address is still on the stack.

miskox
Posts: 555
Joined: 28 Jun 2010 03:46

Re: Exit FOR loop prematurely?

#8 Post by miskox » 18 Apr 2012 00:42

Yes, of course.

Thanks,
Saso

Post Reply