How can I set a value to %%variable in the for /L loop?

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Message
Author
autonicknan
Posts: 19
Joined: 01 Mar 2013 11:44

How can I set a value to %%variable in the for /L loop?

#1 Post by autonicknan » 14 Sep 2014 15:00

Hello,

I need to break a for /L loop violently.
The only way to do this is with goto label but this is not very convenient in my current script.

So what I was thinking is to somehow set the %%variable equal to the end value, but I did not make it up to now.

for /l %%z in (1,1,5) do (
if not exist !header1!_!header2!_%%j%%k%%z.jpg (
rename %%x !header1!_!header2!_%%j%%k%%z.jpg
At this point i need %%z=5
)
)

Any ideas?

Thanks

Br,
Nikos

aGerman
Expert
Posts: 4678
Joined: 22 Jan 2010 18:01
Location: Germany

Re: How can I set a value to %%variable in the for /L loop?

#2 Post by aGerman » 14 Sep 2014 15:27

I need to break a for /L loop violently.
The only way to do this is with goto label but this is not very convenient in my current script.

Unfortunately it's an illusion that you can break a FOR /L loop. You can't break it not even with GOTO. Remove the ECHO OFF in your batch code to see what happens or try the following test code.

Code: Select all

@prompt $
for /l %%i in (1 1 10) do (
  if %%i==5 goto exitloop
  rem ~~~~~~ %%i ~~~~~~
)
:exitloop
pause>nul

Output:

Code: Select all

for /L %i in (1 1 10) do (
if %i == 5 goto exitloop
 rem ~~~~~~ %i ~~~~~~
)

(
if 1 == 5 goto exitloop
 rem ~~~~~~ 1 ~~~~~~
)

(
if 2 == 5 goto exitloop
 rem ~~~~~~ 2 ~~~~~~
)

(
if 3 == 5 goto exitloop
 rem ~~~~~~ 3 ~~~~~~
)

(
if 4 == 5 goto exitloop
 rem ~~~~~~ 4 ~~~~~~
)

(
if 5 == 5 goto exitloop
 rem ~~~~~~ 5 ~~~~~~
)

(
if 6 == 5 goto exitloop
 rem ~~~~~~ 6 ~~~~~~
)

(
if 7 == 5 goto exitloop
 rem ~~~~~~ 7 ~~~~~~
)

(
if 8 == 5 goto exitloop
 rem ~~~~~~ 8 ~~~~~~
)

(
if 9 == 5 goto exitloop
 rem ~~~~~~ 9 ~~~~~~
)

(
if 10 == 5 goto exitloop
 rem ~~~~~~ 10 ~~~~~~
)

pause1>nul

The only way to break a FOR /L loop is using EXIT. But I fear in your case that doesn't help either.

Further more you can't change the value of a FOR variable except with the FOR loop itself.

The easiest solution for your problem would be to create a loop using GOTO.

Regards
aGerman

autonicknan
Posts: 19
Joined: 01 Mar 2013 11:44

Re: How can I set a value to %%variable in the for /L loop?

#3 Post by autonicknan » 15 Sep 2014 01:09

Hello aGerman,

Thanks for your reply.

I had a search in the net before posting and I knew that it is really difficult to break the for /L loop.
For this reason I came up with the idea to change the %%variable value inside the for /L loop, but as you wrote this is not possible.

Unfortunately, the GOTO is not very convenient in my case because I have many nested FOR loops and I cannot create Labels easily.
I will try to find an alternative way of creating my code.

In any case thank you very much for your support!! :)

Br,
Nikos

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

Re: How can I set a value to %%variable in the for /L loop?

#4 Post by foxidrive » 15 Sep 2014 01:27

There may be ways to improve the speed of the loop execution, if you show the code you need to process and discuss where it needs to skip.

I think there are other threads on here which discuss ways of breaking out of loops - I'm not sure it is impossible, aGerman, but I didn't pay close attention to the threads.

aGerman
Expert
Posts: 4678
Joined: 22 Jan 2010 18:01
Location: Germany

Re: How can I set a value to %%variable in the for /L loop?

#5 Post by aGerman » 15 Sep 2014 02:26

I didn't say it's impossible I just said the only way to break a FOR /L loop is using EXIT (neither EXIT /B nor GOTO will work).

Of course we had some discussions about it. I started one of them
http://www.dostips.com/forum/viewtopic.php?t=2707
Also see
viewtopic.php?t=3487

Much easier (and probably faster because you don't need to call another cmd.exe process) is to create a GOTO loop.
The example of autonicknan looks like that FOR /L was nested into one or more other FOR loops where you can't use GOTO directly. In that case you have to outsource the GOTO loop into a sub routine.

Regards
aGerman

autonicknan
Posts: 19
Joined: 01 Mar 2013 11:44

Re: How can I set a value to %%variable in the for /L loop?

#6 Post by autonicknan » 16 Sep 2014 14:51

Hello All,

I had a further googling on this issue and I found the below pretty cool way of breaking a nested for /L loop with using GOTO:

Code: Select all

for %%a in (1,2,3) do (
   echo Top-level loop: %%a
   set break=
   for /L %%b in (4,5,6) do if not defined break (
      echo Nested loop: %%a-%%b
      if %%b == 4 (
         echo Breaking
         set break=yes
      )
   )
)


Most probably for the experts this is a known way of breaking a loop. I am posting this part of code for the beginners in batch programming( like me :) ) which is a useful hint.

Of Course the topics that shared by aGerman(thanks for this) in the previous post are useful but may be more tricky for a beginner are .

Regards,
Nikos

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

Re: How can I set a value to %%variable in the for /L loop?

#7 Post by foxidrive » 17 Sep 2014 01:28

It depends on the application to see if this is useful, but this doesn't actually break out of the loop.

Try the following and it will count to 4 only for the first top-level loop, but then add two more 00 to the 10000 and try it.

Code: Select all

@echo off
set "break="
for %%a in (1,2,3) do if not defined break (
   echo Top-level loop: %%a
      for /L %%b in (1,1,10000) do if not defined break (
         echo Nested loop: %%a-%%b
         if %%b == 4 (
         echo Breaking
         set break=yes
         )
      )
)
pause

bars143
Posts: 87
Joined: 01 Sep 2013 20:47

Re: How can I set a value to %%variable in the for /L loop?

#8 Post by bars143 » 17 Sep 2014 07:12

Hi Foxi,

below code is really called a break loop?

Code: Select all


@echo off

for /l %%i in (1 1 10) do (
  if %%i==5 goto exitloop
  echo -------%%i-----------
)

:exitloop

pause




im using "window xp sp3" now

bars

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

Re: How can I set a value to %%variable in the for /L loop?

#9 Post by foxidrive » 17 Sep 2014 07:18

bars143 wrote:Hi Foxi,

below code is really called a break loop?

Code: Select all


@echo off

for /l %%i in (1 1 10) do (
  if %%i==5 goto exitloop
  echo -------%%i-----------
)

:exitloop

pause




im using "window xp sp3" now

bars


Increase the 10 to 10 million and try it.

aGerman
Expert
Posts: 4678
Joined: 22 Jan 2010 18:01
Location: Germany

Re: How can I set a value to %%variable in the for /L loop?

#10 Post by aGerman » 17 Sep 2014 14:48

Code: Select all

@echo off &setlocal
for %%a in (1,2,3) do (
  set /a "c = 0, n = %%a"
  call :loop
)
pause
exit /b

:loop
set /a "c += 1"
echo Iteration %c% in Top-Level %n%
if %c% lss 5 goto loop
exit /b

or vice versa

Code: Select all

REM ... same as above ...

:loop
set /a "c += 1"
if %c%==5 exit /b
echo Iteration %c% in Top-Level %n%
goto loop

:wink:
As mentioned before I don't see an easier way ...

Regards
aGerman

bars143
Posts: 87
Joined: 01 Sep 2013 20:47

Re: How can I set a value to %%variable in the for /L loop?

#11 Post by bars143 » 17 Sep 2014 17:52

foxidrive wrote:
bars143 wrote:Hi Foxi,

below code is really called a break loop?

Code: Select all


@echo off

for /l %%i in (1 1 10) do (
  if %%i==5 goto exitloop
  echo -------%%i-----------
)

:exitloop

pause




im using "window xp sp3" now

bars


Increase the 10 to 10 million and try it.




foxi,

i increase 10 to 10000000,then

my console shows that it still stopped at 4 but without showing:

"Press any key to continue . . ."

and my CPU increase from 4% to 60% !

foxi, why it has no error message to display in console that its still running and why "pause" does not work?

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

Re: How can I set a value to %%variable in the for /L loop?

#12 Post by foxidrive » 17 Sep 2014 20:39

bars143 wrote:foxi, why it has no error message to display in console that its still running and why "pause" does not work?


The loop is still running and it will execute the full 10 million times before the pause command is reached.

It is just not displaying any text and is not running any commands


So the technique of goto :label does stop a set of commands within the loop from executing,
but the loop is still going around in circles until the target number is reached.

It doesn't break out of the loop cleanly.

bars143
Posts: 87
Joined: 01 Sep 2013 20:47

Re: How can I set a value to %%variable in the for /L loop?

#13 Post by bars143 » 17 Sep 2014 23:21

foxidrive wrote:
bars143 wrote:foxi, why it has no error message to display in console that its still running and why "pause" does not work?


The loop is still running and it will execute the full 10 million times before the pause command is reached.

It is just not displaying any text and is not running any commands


So the technique of goto :label does stop a set of commands within the loop from executing,
but the loop is still going around in circles until the target number is reached.

It doesn't break out of the loop cleanly.


foxi, thanks for reply

and the code below work on "call" but "goto" does not:


@echo off

title stoploop

for /l %%i in (1 1 10000000) do (
if %%i==5 call :exitloop
echo -------%%i-----------
)

:exitloop

ping localhost -n 10

start "" notepad

TASKKILL /F /FI "WINDOWTITLE eq stoploop"


pause



does above code a true loop-break script?


Bars

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

Re: How can I set a value to %%variable in the for /L loop?

#14 Post by foxidrive » 17 Sep 2014 23:52

Using your call :label idea it's possible to branch to the label and execute the rest of the batch file, and
finally exit the script.

Code: Select all

@echo off

for /l %%i in (1 1 10000000) do (
if %%i==5 call :exitloop
if %%i==5 pause & exit
echo -------%%i-----------
)
:exitloop

rem execute more code and for loops here
echo the batch file will exit when this point is reached


bars143 wrote:and the code below work on "call" but "goto" does not:

TASKKILL /F /FI "WINDOWTITLE eq stoploop"

does above code a true loop-break script?


Using taskkill you are killing the batch file - that is fine if you just want to exit the script completely, and exit alone can do that

Code: Select all

@echo off
for /l %%i in (1 1 10000000) do (
if %%i==5 exit
echo -------%%i-----------
)


The idea was to exit a loop and continue the script, and your technique seems to allow that to be done.

aGerman wrote:As mentioned before I don't see an easier way ...

Regards
aGerman


I don't see any drawback from bars143's method, do you?

bars143
Posts: 87
Joined: 01 Sep 2013 20:47

Re: How can I set a value to %%variable in the for /L loop?

#15 Post by bars143 » 18 Sep 2014 05:13

hi, foxi

i found out why "goto" does not execute when specified number 100 is reached.

Code: Select all


@echo off


for /l %%i in (1 1 500) do (

if %%i==100 pause & echo on & goto :exitloop
echo -------%%i-----------

)

:exitloop
echo verifying loop number before executing notepad
pause

notepad



it stop at 100 and im thinking that next run will be executing notepad by goto label

however, after keying any key to continue --it continue to loop up to 500 before notepad is executed!


Bars

Post Reply