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”


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:



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=



Comments (2)

  1. Jeremy says:

    FYI, you can use "setlocal enabledelayedexpansion" inside your script itself, so that you do not need your test.

  2. Anonymous says:

    Either of these won't necessarily work when you want to edit the variables in the current shell (and keep the side-effects after the batch file has ended).

    I found this trick using CALL works.

    set haystack=ABCDEFG

    set needle=DEF

    call :Setvar set THING=%%haystack:%needle%=__REPLACED__%%

    echo Thing is %THING%

    goto :EOF



       goto :EOF