Batch File String Substitution with Nested Environment Variables

The SET command has some nice extensions that let you do various manipulation operations on environment variables. One said operation is the string substitution feature, which is often used to perform basic pattern replacements such as stripping out quotes around filenames: 

set ABC="c:\foo.txt"
set ABC=%ABC:"=%
echo %ABC%

In the above sample, the quotes around the filename are removed (the search pattern is located between the colon and the equal sign, and the replacement pattern is located after the equal and before the ending percent sign – which is empty in this case).

I recently had a need to replace the beginning portion of a path name, with a different directory. But, unfortunately, I wasn't able to use hard-coded pattern strings as the both the initial directory and the replacement were unknown beforehand. This meant that I was left with the unfortunate task of trying to use an environment variable inside of the replacement syntax. Needless to say, nesting % signs didn't go very well for me.

 

Luckily, there is a mode of cmd.exe which support delayed environment evaluation, and offers a new syntax for evaluating the environment variable.

 

cmd.exe /v

 

When /v is passed into cmd.exe, it allows you to expand environment variables using ! instead of %:

 

echo !ABC!

 

Using both forms of expansion, I can nest one inside of the other, allowing me to use a variable for both the search string as well as the replacement:

 

set TARGETPATH=!TARGETPATH:%ROOT%=%NEWROOT%!

As an aside, here is a little test which will let you determine if /v is enabled or not:

set _EXP=expanded
if "!_EXP!" NEQ "expanded" echo ERROR: You must start cmd.exe with /v & goto :eof
set _EXP=