Page 1 of 2

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

Posted: 14 Sep 2014 15:00
by autonicknan
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

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

Posted: 14 Sep 2014 15:27
by aGerman
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

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

Posted: 15 Sep 2014 01:09
by autonicknan
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

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

Posted: 15 Sep 2014 01:27
by foxidrive
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.

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

Posted: 15 Sep 2014 02:26
by aGerman
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

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

Posted: 16 Sep 2014 14:51
by autonicknan
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

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

Posted: 17 Sep 2014 01:28
by foxidrive
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

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

Posted: 17 Sep 2014 07:12
by bars143
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

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

Posted: 17 Sep 2014 07:18
by foxidrive
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.

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

Posted: 17 Sep 2014 14:48
by aGerman

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

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

Posted: 17 Sep 2014 17:52
by bars143
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?

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

Posted: 17 Sep 2014 20:39
by foxidrive
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.

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

Posted: 17 Sep 2014 23:21
by bars143
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

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

Posted: 17 Sep 2014 23:52
by foxidrive
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?

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

Posted: 18 Sep 2014 05:13
by bars143
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