This page is edited from the 1cmdfaq.txt faq-file contained in
my tscmd.zip
command line interface (CLI) collection. That zipped file has much
additional material, including a number of detached .cmd script
files. It is recommended that you also get the zipped version as a
companion.
Please see "
The Description and
the Index page" for the conditions of usage and other such
information.
141} Why isn't the ! character always echoed as expected?
This is a result of a side effect. The exclamation mark is used to
expand environment variables at execution time if the delayed
variable expansion is enabled in a script. This affects how the !
character is treated. Note the different outputs in the following
demonstration:
@echo off
setlocal enableextensions enabledelayedexpansion
echo delayed expansion enabled
echo.WOW!!!
echo.WOW^!^!^!
echo.WOW^^!^^!^^!
echo.! test! addition suggested by foxidrive!
echo.!test! addition suggested by foxidrive!
setlocal enableextensions disabledelayedexpansion
echo.
echo delayed expansion disabled
echo.WOW!!!
echo.WOW^!^!^!
echo.WOW^^!^^!^^!
echo.! test! addition suggested by foxidrive!
echo.!test! addition suggested by foxidrive!
endlocal & goto :EOF
The output will be
C:\_D\TEST>cmdfaq
delayed expansion enabled
WOW
WOW
WOW!!!
test
addition suggested by foxidrive
delayed expansion disabled
WOW!!!
WOW!!!
WOW^!^!^!
! test! addition suggested by foxidrive!
!test! addition suggested by foxidrive!
Browse throughout the items in this FAQ for several examples of
using the delayed expansion for its actual purpose. For example,
consider the task of listing today's files in the current folder.
One of the possible ways of formulating that is
@echo off & setlocal enableextensions enabledelayedexpansion
for %%f in ("*.*") do (
echo "%%~tf" | find "%date%" > nul
if !errorlevel! EQU 0 echo %%~tf %%~zf "%%~ff"
)
endlocal & goto :EOF
The output might be
C:\_D\TEST>cmdfaq
20.05.2006 10:10 21928 "C:\_D\TEST\BATFAQ2.BAT"
20.05.2006 10:22 216 "C:\_D\TEST\CMDFAQ.CMD"
Note
!errorlevel! not
%errorlevel%.
Incidentally, in this particular case also the following formulation
would work
if not errorlevel 1 echo %%~tf %%~zf "%%~ff"
but even if important formulation lore that is beside the current
point on delayed expansion.
Aligning the output demontrates further
@echo off & setlocal enableextensions enabledelayedexpansion
for %%f in ("*.*") do (
echo "%%~tf" | find "%date%" > nul
if not errorlevel 1 (
set fdate=%%~tf
set fsize=%%~zf
set fsize= !fsize!
set fsize=!fsize:~-10!
set fname="%%~ff"
echo !fdate! !fsize! !fname!
)
)
endlocal & goto :EOF
The output might be
C:\_D\TEST>cmdfaq
20.05.2006 10:10 21928 "C:\_D\TEST\BATFAQ2.BAT"
20.05.2006 10:19 372 "C:\_D\TEST\CMDFAQ.CMD"
A related problem asked in alt.mdsosbatch.nt. Suppose there is a
file C:\WHEREVER\LIST.TXT containing a list of file names such as
C:\_D\TEST\TEST!.TXT
C:\_D\TEST\TEST%.TXT
To perform an example operation on those files use the following
kind of syntax
@echo off & setlocal enableextensions disabledelayedexpansion
for /f "tokens=*" %%f in ("c:\wherever\list.txt") do type "%%f"
endlocal & goto :EOF
Also see
item #146
and
item #47.
For additional echo tips see the item links at the end of
item #17.