Using SetDelayedExpansion in batch files: handling dirs / filenames containing!

I have two batch files (XP):

test.bat:

setlocal EnableDelayedExpansion

rem check for argument
if [%1]==[] goto :noarg

:arg
rem check for trailing backslash and remove it if it there
set dirname=%1
IF !dirname:~-1!==\ SET "dirname=!dirname:~0,-1!"

rem find all log files in passed directory and call test2.bat for each one
for /f "tokens=* delims= " %%a in ('dir !dirname!\*.log /s /b') do call test2.bat "%%a"

goto :finish

:noarg
rem prompt for directory to scan
set /p dirname=Type the drive or directory, then hit enter: 

rem loop if nothing entered
if [!dirname!]==[] goto :noarg

rem check for trailing backslash and remove it if it there
IF !dirname:~-1!==\ SET "dirname=!dirname:~0,-1!"

rem find all log files in passed directory and call test2.bat for each one
for /f "tokens=* delims= " %%a in ('dir "!dirname!"\*.log /s /b') do call test2.bat "%%a"

goto :finish

:finish

test2.bat:

echo %1

Demonstration of the problem:

-Create the c: \ test directory and the other c: \ test! and put the empty test.log file in each directory.

Then run:

test c:\test

Works as expected (test2.bat echo "c: \ test \ test.log")

Now run:

test c:\test!

The problem is that test2.bat performs an echo test "c: \ test \ test.log" instead of the desired "c: \ test! \ Test.log")

, , ! EnableDelayedExpansion. "% ", , DelayedExpansion ( )

:

setlocal DisableDelayedExpansion

endlocal

! cmd?

( PEBCAK).

?

+3
1

% 1 %% a, ! .
.
Btw. (EDIT: true, )

setlocal DisableDelayedExpansion

rem check for argument
if "%~1"=="" goto :noarg

:arg
set "dirname=%~1"

rem find all log files in passed directory and call test2.bat for each one
for /f "tokens=* delims=" %%a in ('dir "%dirname%\*.log" /s /b') do (
  set "file=%%~a"
  setlocal EnableDelayedExpansion
  echo found #!file!#
  call test2.bat "!file!"
  endlocal
)
+2

All Articles