The help for command SET output on running in a command prompt window set /?
explains on an IF and a FOR example similar to code in question when and how to use delayed environment variable expansion.
@echo off
setlocal EnableExtensions EnableDelayedExpansion
set "A=test batch"
set "b=ing"
set "C="
for %%I in (%A%) do set "C=!C! %%I%b%"
rem Remove the space character at beginning.
set "C=%C:~1%"
echo %C%
endlocal
pause
All !
in strings are interpreted by the code above as begin/end of a delayed expanded environment variable reference resulting in wrong processing as it can be seen by using set "b=ing!"
in fourth line or even more worse using set "A=!test! batch"
in third line.
There is another solution which avoids the usage of delayed environment variable expansion and for that reason is working also for strings containing one or more exclamation marks.
@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "A=test batch"
set "b=ing"
set "C="
for %%I in (%A%) do call set "C=%%C%% %%I%b%"
rem Remove the space character at beginning.
set "C=%C:~1%"
echo %C%
endlocal
pause
The environment variable C
is referenced with %%
on both sides resulting in FOR command line being processed by Windows command processor to the following before execution of command FOR:
for %I in (test batch) do call set "C=%C% %Iing"
The command CALL results in one more processing of set "C=%C% %Iing"
before execution of command SET on which %C%
is replaced by current value of environment variable C
.
See also: