Cmd y signos de exclamación - Parte II

Realmente me pregunto por qué mi procedimiento de reemplazo de cadenas funciona al analizar archivos de texto que contienen caracteres especiales, incluidos signos de exclamación. Esperaba que la expansión de la variable retrasada desactivara el significado especial de ampersand, el signo de porcentaje, etc.

Código:

@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

Sintaxis de línea de comando:

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

EDITAR / Suplemento:

Después de 1 1/2 años tuve que usar este fragmento de código nuevamente. Vea dos ejemplos adicionales que manejan caracteres envenenados. El primero con la expansión demorada habilitada temporalmente nuevamente (ver la respuesta de Ansgars), el segundo usandoCALL. Ambos analizarán la ruta y el nombre de los archivos que no están vacíos en y debajo del directorio actual, pero sin la letra de unidad y la ruta al directorio actual.

Ejemplo # 1 (Incluyendo comillas dobles enset "File=!File..." yecho "!FILE!">>... no son necesarios):

@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

Ejemplo # 2 (más lento, entre comillas dobles requeridas):

@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

Archivos y carpetas para la prueba:

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

Salida:

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"

Disfrutar de la preparación de lotes! Martín

Respuestas a la pregunta(1)

Su respuesta a la pregunta