Cmd и восклицательные знаки - часть II

Мне действительно интересно, почему моя процедура замены строк работает при разборе текстовых файлов, содержащих любые специальные символы, включая восклицательные знаки. Я ожидал, что отложенное расширение переменной отключит особое значение амперсанда, знака процента и т. Д., Но вместо восклицательных знаков произойдет сбой ...

Код:

@echo on & setlocal ENABLEEXTENSIONS

set "InFile=%~1"
set "OutFile=%~2"
set "Replace=%~3"

CALL :ParseCue "%%InFile%%" "%%OutFile%%" "%%Replace%%"

endlocal &GOTO:EOF

:ParseCue
@echo on & setlocal ENABLEEXTENSIONS DISABLEDELAYEDEXPANSION
set "FileToParse=%~1"
set "OutputFile=%~2"
set "NewExtension=%~3"
for /F "usebackq tokens=* delims=" %%a in ("%FileToParse%") DO (
  set "line=%%a"
  @echo on & setlocal ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
  set "line=!line:.wav=%NewExtension%!"
  echo(!line!>>"%OutputFile%"
  endlocal
)
endlocal &GOTO:EOF

InputFile.txt:

This a test for parsing lines with special characters
Rock & Roll.wav
Rock & Roll!.wav
Special | < > ~ \ ²³ { [ ] } ! " ´ ' ` üäö @ ; : € $ % & / ( ) = ? chars.wav

Синтаксис командной строки:

D:\Users\Public\Batch\YAET>parse.bat "InputFile.txt" "OutputFile.txt" ".flac"

OutputFile.txt:

This a test for parsing lines with special characters
Rock & Roll.flac
Rock & Roll!.flac
Special | < > ~ \ ²³ { [ ] } ! " ´ ' ` üäö @ ; : € $ % & / ( ) = ? chars.flac

РЕДАКТИРОВАТЬ / Дополнение:

Через полтора года мне снова пришлось использовать этот фрагмент кода. Смотрите два дополнительных примера обработки ядовитых символов. Первый с временным включенным отложенным расширением снова (см. Ответ Ansgars), второй с использованиемCALL, Оба будут анализировать путь и имя непустых файлов в текущем каталоге и под ним, но без конечной буквы диска и пути к текущему каталогу.

Пример № 1 (Заключение двойных кавычек вset "File=!File..." а такжеecho "!FILE!">>... не требуются):

@echo off & setlocal ENABLEEXTENSIONS DISABLEDELAYEDEXPANSION
del NonEmptyFiles.txt >NUL 2>&1
echo Searching non-empty files in and below current directory ...
for /f "tokens=*" %%I in ('dir /s /b /a:-D') do (
    if not %%~zI==0 (
        set "File=%%I"
        setlocal ENABLEDELAYEDEXPANSION
        set "File=!File:%cd%\=!"
        echo "!File!">> NonEmptyFiles.txt
        endlocal
        )
    )
echo Done. See NonEmptyFiles.txt.
endlocal &goto:EOF

Пример № 2 (медленнее, требуется заключать в двойные кавычки):

@echo off & setlocal ENABLEEXTENSIONS DISABLEDELAYEDEXPANSION
del NonEmptyFiles.txt >NUL 2>&1
echo Searching non-empty files in and below current directory ...
for /f "tokens=*" %%i in ('dir /s /b /a:-D') do (
    if not %%~zi==0 (
        set "File=%%i"
        call set "File=%%File:%cd%\=%%"
        call echo "%%File%%">> NonEmptyFiles.txt
        )
    )
echo Done. See NonEmptyFiles.txt.
endlocal &goto:EOF

Файлы и папки для тестирования:

D:\Martin\Any & Path>dir /s /b /a:-D
D:\Martin\Any & Path\Hello! World!.txt
D:\Martin\Any & Path\Rock & Roll\!File! !!File!!.txt
D:\Martin\Any & Path\Rock & Roll\%File% %%File%% %%I.txt
D:\Martin\Any & Path\Rock & Roll\Poison! !§$%&()=`´'_;,.-#+´^ßöäüÖÄÜ°^^#.txt
D:\Martin\Any & Path\Rock & Roll\SizeZero.txt

Выход:

D:\Martin\Any & Path>stringinforloop.bat
Searching non-empty files in and below current directory ...
See NonEmptyFiles.txt. Done.

D:\Martin\Any & Path>type NonEmptyFiles.txt
"Hello! World!.txt"
"Rock & Roll\!File! !!File!!.txt"
"Rock & Roll\%File% %%File%% %%I.txt"
"Rock & Roll\Poison! !§$%&()=`´'_;,.-#+´^ßöäüÖÄÜ°^^#.txt"

Наслаждайтесь дозированием! Мартин

Ответы на вопрос(1)

Ваш ответ на вопрос