|
Answer» Hi there
I'm writing an incremental file BACKUP utility from the windows cmd prompt (XP Pro SP3) mostly for the fun of it (!) and am having trouble handling filenames containing the ! (exclamation point) character. The ! seems to disappear from the filename before I can escape it, e.g.: Code: [Select]SETLOCAL ENABLEDELAYEDEXPANSION ENABLEEXTENSIONS echo.>"file^! a.txt" for %%A in ("*.txt") do set MYFILE="%%~A" set myfile=%myfile:!=^^!% echo %myfile% ENDLOCALIn the above example, the ! is visible in the set generated by the for statement, but is gone immediately afterwards. - all PATHS and filenames are held in quoted vars e.g. set FNAME="c:\path\name.ext" - I have tried escaping the ! with ^, ^^, and ^^^ without any success so far - I need ENABLEDELAYEDEXPANSION for various bits of script throughout the cmd file
Any ideas?
Slainte
midders P.S. alternatively; is it possible to turn ENABLEDELAYEDEXPANSION on and off without creating a new local environment? I've thought about just turning it on when it's needed and then using files to pass the vars back to the original environment, but it's a bit clunky and I was hoping to come up with a better solution.First off, in a for loop while delayed expansions are enabled, you need to replace the % (in regular variables) with !. Try using this code to escape the path.
Set myfile=!myfile:^!=^^^!! Thanks for the response, but the line escaping the ! is not in the for loop, and AFAIK you can't use the :X= substitution syntax with for statement vars.
Also, the syntax you suggested (!myfile:^!=^^^!!) is invalid; it is treated by the shell as !myfile:^! and !=^^^! because the ! character takes precedence over everything else, even if it is escaped.Update:
I've implemented the file-based kludge that I referred to in my earlier post; i.e. SETLOCAL DISABLEDELAYEDEXPANSION globally and then use this sort of thing inside subroutines: Code: [Select]SETLOCAL ENABLEDELAYEDEXPANSION echo "!_TMPSTR:~%NSTART%,1!:!_TMPSTR:~%LEN_STUB%,%NCOUNT%!">"%TEMP%\cmdbak.var" ENDLOCAL set /p RETURN_VAR=<"%TEMP%\cmdbak.var" del /f "%TEMP%\cmdbak.var">nul 2>nul The result is that filenames with ! in them now work ok. However; filenames with % in them still fail. I've found that the special chars (!,%) are only retained in the unmodified for variable (%%A etc.), the moment that you assign it to another variable they are lost in translation.
I've found that I can use the same file-based kludge to preserve the special chars, but I'd still like to hear from anyone that has a better way.
Code: [Select]@SETLOCAL DISABLEDELAYEDEXPANSION ENABLEEXTENSIONS echo.>"file%% a !b.txt" for %%A in ("*.txt") do echo %%A>"%TEMP%\var.tmp"&call :FUNC_X "%TEMP%\var.tmp" goto :FINISHED
:FUNC_X set /p fname=<%1 echo %fname% goto :EOF
:FINISHED endlocal
|