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's 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's 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
Demonstrating the problem:
-Create a directory called c:\test and another called c:\test! and put an empty test.log file in each directory.
Then run:
test c:\test
This works as expected (test2.bat echoes "c:\test\test.log")
Now r开发者_运维百科un:
test c:\test!
The problem is that test2.bat echoes "c:\test\test.log" instead of the desired "c:\test!\test.log")
I realize this is because ! is reserved for EnableDelayedExpansion use. But if the solution is "use % expansion", then I'm hung because I need to use DelayedExpansion (per Handling trailing backslash & directory names with spaces in batch files )
I've poked around with:
setlocal DisableDelayedExpansion
and
endlocal
and How can I escape an exclamation mark ! in cmd scripts?
with no luck (could be PEBCAK).
Any thoughts?
The problems are the expansions of %1 and %%a, with delayed expansion the ! is removed.
So you should first disable the delayed expansion.
Btw. Removing the trailing slash is not neccessary (EDIT: only true, if it is not a root path)
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
)
精彩评论