<http://www.netikka.net/tsneti/info/tscmd141.htm>
Copyright © 2003-2011 by Prof. Timo Salmi  
Last modified Thu 8-Dec-2011 10:17:22

 
Assorted NT/2000/XP/.. CMD.EXE Script Tricks
From the html version of the tscmd.zip 1cmdfaq.txt file
To the Description and the Index
 

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.