Wednesday, April 18, 2012

Environment Variables in FOR loops

Let’s say you want to run a program multiple times. The output of each execution should be stored in a separate file to allow for easy comparison. The output filename has useful information so it would be nice to simply append a counter to indicate which run a given output file is associated with. In other words run 1 produces output-1, run 2 produces output-2, …, run N produces output-N.

If you’ve ever tried this using .bat files on windows you might have come up with something along the lines of the following:

@echo off
set f=%1

for /l %%i in (1,1,5) do (
set nf=%f%-%%i

if not exist %nf% (
echo %nf% does not exist
) else (
echo %nf% does exist
)
)


Which surprisingly produces output along the lines of output-5, output-5, output-5, ….



By default the command interpreter CMD only evaluates environment variables (nf in this case) once. To evaluate environment variables more than once it is necessary to enable “delayed environment variable expansion".



This can be enabled when the CMD is started with /v:on. (e.g., cmd /v:on). Alternatively, it can be enabled via setlocal enabledelayedexpansion in an already running CMD prompt.



However, %nf% must replaced with !nf! to get the value of the variable based on the current iteration of the enclosing FOR loop.



So the corrected code is:



@echo off
set f=%1

setlocal enabledelayedexpansion

for /l %%i in (1,1,5) do (
REM set nf=!f!-%%i
set nf=%f%-%%i

if not exist !nf! (
echo !nf! does not exist
) else (
echo !nf! does exist
)
)

endlocal

No comments :

Post a Comment