Ejemplo de expansión retrasada en archivo por lotes

¿Puede alguien darme un ejemplo de dónde un script por lotes actuaría de manera diferente con o sin demora en la expansión? ¿Hay alguna situación en la que NO desee utilizar la expansión retrasada? Gracias.

Mira los siguientes ejemplos …

Ejemplo 1: El siguiente código NO utiliza expansión retrasada, por lo que las variables en el ciclo for se expanden solo una vez. Esto significa que %Count% siempre se expandirá a 0 en cada iteración del ciclo, sin importar lo que le hagamos con el comando set:

 @echo off set COUNT=0 for %%v in (1 2 3 4) do ( set /A COUNT=%COUNT% + 1 echo Count = %COUNT% ) pause 

Entonces este script dará como resultado:

 Count = 0 Count = 0 Count = 0 Count = 0 

Esta no es la forma en que se supone que funciona este bucle.

Ejemplo 2: Por otro lado, si usamos la expansión retrasada, tenemos la siguiente secuencia de comandos, que se ejecutará como se esperaba.

 setlocal ENABLEDELAYEDEXPANSION set COUNT=0 for %%v in (1 2 3 4) do ( set /A COUNT=!COUNT! + 1 echo Count = !COUNT! ) pause 

y, como se esperaba, dará salida:

 Count = 1 Count = 2 Count = 3 Count = 4 

Cuando usa ENABLEDELAYEDEXPANSION , y expande una variable usando ! en lugar de % , la variable se vuelve a expandir cada vez y todo funciona como debe.

La respuesta de Max brinda un ejemplo de dónde un script por lotes actuaría de manera diferente con o sin demora en la expansión .

En aras de la exhaustividad, respondamos otra parte de la pregunta y muestre una situación en la que NO desee utilizar la expansión retrasada cuando sus datos contengan un signo de exclamación ! (y muestra dos formas de procesar tales datos):

 @ECHO OFF SETLOCAL EnableExtensions DisableDelayedExpansion set "_auxFile=%temp%\%~n0.txt" rem create multiline sample file >"%_auxFile%" ( for /L %%G in (1,1,3) do echo line %%G is 100%% valid! Sure! Hurrah!) rem create one-line sample file >"%_auxFile%" echo this line is 100%% valid! Sure! Hurrah! echo( echo --- file content type "%_auxFile%" echo( SETLOCAL EnableDelayedExpansion echo --- enabled delayed expansion chokes down unescaped exclamation marks^^^! "^!" for /F "usebackq delims=" %%G in ("%_auxFile%") do ( set "_auxLine=%%~G" echo loop var=%%~G echo _auxLine=!_auxLine! ) ENDLOCAL echo( SETLOCAL DisableDelayedExpansion echo --- toggled delayed expansion works although might be laborious! for /F "usebackq delims=" %%G in ("%_auxFile%") do ( set "_auxLine=%%G" echo loop var=%%G SETLOCAL EnableDelayedExpansion echo _auxLine=!_auxLine! ENDLOCAL ) ENDLOCAL echo( SETLOCAL DisableDelayedExpansion echo --- keep delayed expansion DISABLED: use CALL command! for /F "usebackq delims=" %%G in ("%_auxFile%") do ( set "_auxLine=%%G" echo loop var=%%G call :ProcessVar ) ENDLOCAL rem delete the sample file del "%_auxFile%" ENDLOCAL goto :eof :ProcessVar echo _auxLine=%_auxLine% echo WARNING: neither !_auxLine! nor %%G loop variable is available here! goto :eof 

Tenga en cuenta que el script anterior muestra formas adecuadas de escapar

  • % signo por %% duplicándolo (la expansión demorada no importa) y
  • ! signo de exclamación si la expansión retrasada está habilitada:
    • "^!" si está encerrado en un par de comillas dobles, utilice el carácter de escape general cmd y batch-script ^ caret;
    • ^^^! de lo contrario, use tres ^ carentes.

Salida :

 ==> D:\bat\SO\10558316.bat --- file content this line is 100% valid! Sure! Hurrah! --- enabled delayed expansion chokes down unescaped exclamation marks! "!" loop var=this line is 100% valid Hurrah _auxLine=this line is 100% valid Hurrah --- toggled delayed expansion works although might be laborious! loop var=this line is 100% valid! Sure! Hurrah! _auxLine=this line is 100% valid! Sure! Hurrah! --- keep delayed expansion DISABLED: use CALL command! loop var=this line is 100% valid! Sure! Hurrah! _auxLine=this line is 100% valid! Sure! Hurrah! WARNING: !_auxLine! as well as %G loop variables are not available here! ==> 

Quería agregar un gran ejemplo sobre cómo “EnableDelayedExpansion” (EDE) puede ser útil fuera de los omnipresentes ejemplos FOR loop.

Aquí hay una línea de datos de terremotos que deseo analizar (lo llamo 1 línea.txt)

ak_11574812 2015.04.29.193822 62.9525 -148.8849 1.0 9.5 1 49 km S de Cantwell, Alaska

El problema con el que me encontré fue que el último segmento de esta línea no siempre comienza en el mismo número de columna. Por lo tanto, necesitaba crear un comando SET flexible que recortara con precisión el último segmento de esta línea.

 ECHO OFF setlocal enableDelayedExpansion set where=72 set /p line=<1line.txt set locate=!line:~%where%,28! echo %locate% 

EDE me permite colocar una variable (donde) dentro de otra variable (línea). EDE traducirá la variable entre corchetes por% primero, luego procesará la variable entre corchetes. y (en este caso) enviar los resultados a la variable "localizar".