batch-file - personalizar - los mejores archivos bat
Ejemplo de expansión retrasada en archivo por lotes (3)
¿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.
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".
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 generalcmd
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!
==>