Empty variables during FOR loops in batch files

Written by Ingmar Verheij on April 27th, 2010. Posted in Batch

Batch files (*.bat / *.cmd) are easy to build and yet powerful scripts .
Although time is catching up and batch files are more and more replaced by vbScript and PowerShell, there are occasions you need them.
Batch files are especially powerful when you’re using (for) loops and variables. But the combination of those two is somewhat of a problem. Why? It doesn’t (seem to) work…
Let’s take the following situation.
You want to build a script that searches for files with a given extension in a given directory. You then strip the extension of the filename and process the file. This script would look like this:
@ECHO OFF
REM Set constants
REM -------------
SET strSourceDirectory=C:App-V
SET strWildcard=*.osd

REM Search for files
REM ----------------
FOR /F "tokens=* delims=" %%A IN ('DIR /B /S %strSourceDirectory%%strWildcard%') DO (
REM Determine filename
REM ------------------
SET strFileName=%%A
REM Determine filename without extension
REM ------------------------------------
SET strFileNameWithoutExtension=%strFilename:~0,-4%
ECHO Filename = %strFileNameWithoutExtension%
)

You would expect a list of files without the extension (.osd is 4 characters). However, the outcome of the script looks like this:

Filename =
Filename =
Filename =
Filename =

There is no result, no outcome. Not what you would expect.
The reason for this lies in the way a batch file processes variables (or expands the variables). This doesn’t happen during command execution, but before execution. Of course you can solve this issue. By enabling delayed variable expansion and reading the variables the right way.
First of all you need to enable delayed variable expansion. This can be achieved by calling the command interpreter via the command CMD /V:ON /C or simply by adding SETLOCAL ENABLEDELAYEDEXPANSION in the batch file.
Next you need to read the variables on a different way. Not with percent signs, like you’re used to, but with exclamation marks.
Let take a look at the same script, but this time with delayed variables expansion.
@ECHO OFF
REM Enable delay expansion
REM ----------------------
SETLOCAL ENABLEDELAYEDEXPANSION

REM Set constants
REM -------------
SET strSourceDirectory=C:App-V
SET strWildcard=*.osd
REM Search for files
REM -----------------
FOR /F "tokens=* delims=" %%A IN ('DIR /B /S %strSourceDirectory%%strWildcard%') DO (
REM Determine filename
REM ------------------
SET strFileName=%%A
REM Determine filename without extension
REM ------------------------------------
SET strFileNameWithoutExtension=!strFilename:~0,-4!
ECHO Filename : !strFileNameWithoutExtension!
)

Now if we execute the batch file, this would be the result. As expected.

Filename = C:App-VGlobalSoftGrid ClientOSD Cacheffd89791-cecb-4550-a3b3-3d9805961e13
Filename = C:App-VGlobalSoftGrid ClientOSD Cacheffd89791-cecb-4550-a3b3-3d9805961e13
Filename = C:App-VGlobalSoftGrid ClientOSD Cacheffd89791-cecb-4550-a3b3-3d9805961e13
Filename = C:App-VGlobalSoftGrid ClientOSD Cacheffd89791-cecb-4550-a3b3-3d9805961e13

Ingmar Verheij

Ingmar Verheij

At the time Ingmar wrote this article he worked for PepperByte as a Senior Consultant (up to May 2014). His work consisted of designing, migrating and troubleshooting Microsoft and Citrix infrastructures. He was working with technologies like Microsoft RDS, user environment management and (performance) monitoring. Ingmar is User Group leader of the Dutch Citrix User Group (DuCUG). RES Software named Ingmar RES Software Valued Professional in 2014.

More Posts - Website

Follow Me:
TwitterLinkedInGoogle Plus

Tags: , , , , ,

Leave a comment

*

Donate

%d bloggers like this: