Expansión retardada
Actualizas una variable dentro de un bucle FOR o un bloque IF de un archivo por lotes, pero echo sigue mostrando el valor anterior. Es uno de los problemas más comunes al escribir archivos por lotes.
La solución es la expansión retardada de variables de entorno.
En resumen: añade setlocal enabledelayedexpansion y sustituye %variable% por !variable! dentro del bloque. Este artículo explica el momento de expansión que causa el problema y muestra cómo usar la expansión retardada con ejemplos.
El problema: las variables no se actualizan dentro de los bloques
Observa el siguiente archivo por lotes.
@echo off
setlocal
set COUNT=0
for %%f in (*.txt) do (
set /a COUNT+=1
echo Archivo %COUNT%: %%f
)
echo Total: %COUNT%
endlocal
El script intenta contar los archivos de texto, pero el resultado no es el esperado.
COUNT se muestra siempre como 0.
La causa: cuándo se expanden las variables
En los archivos por lotes, un bloque entre paréntesis () se analiza completo antes de ejecutarse. Durante el análisis, %variable% se sustituye por el valor que tenía antes de que empezara el bloque.
En el ejemplo anterior, %COUNT% se sustituye por 0 (su valor antes del bucle for), por lo que actualizarla dentro del bucle no tiene efecto visible.
rem Al analizar todo el bloque, %COUNT% se sustituye por 0
for %%f in (*.txt) do (
set /a COUNT+=1
echo Archivo 0: %%f <- %COUNT% ya se ha convertido en 0
)
La solución: activar la expansión retardada
Activa la expansión retardada y usa !variable! en lugar de %variable%. Así la variable se expande en tiempo de ejecución.
Pasos
- Escribe
setlocal enabledelayedexpansion - Cambia las referencias a variables dentro del bloque por
!variable!
@echo off
setlocal enabledelayedexpansion
set COUNT=0
for %%f in (*.txt) do (
set /a COUNT+=1
echo Archivo !COUNT!: %%f
)
echo Total: !COUNT!
endlocal

中小企業経営者のためのRPA入門 RPA導入を成功させる方法

60分でわかる! AIエージェント 超 入門

コマンドラインの黒い画面が怖いんです。

知識・才能ゼロでもらく~に月10万円稼ぐ! よくわかるAI副業超入門
Ahora COUNT se incrementa correctamente.
%variable% frente a !variable!
| Sintaxis | Se expande | Uso |
|---|---|---|
%variable% | Al analizar | Referencias normales fuera de bloques |
!variable! | Al ejecutar | Variables que cambian dentro de un bloque |
setlocal enabledelayedexpansion tiene efecto hasta el endlocal correspondiente (o hasta el final del archivo por lotes si no lo hay). Además, endlocal restaura las variables modificadas dentro de setlocal. Para activarla en todo el script, escríbela al principio del archivo.
El mismo problema en bloques IF
El mismo problema ocurre en bloques IF, no solo en bucles FOR.
@echo off
setlocal
set RESULT=NG
if exist "data.txt" (
set RESULT=OK
echo Resultado: %RESULT%
)
Aunque data.txt exista, se muestra Resultado: NG. Se corrige con la expansión retardada.
@echo off
setlocal enabledelayedexpansion
set RESULT=NG
if exist "data.txt" (
set RESULT=OK
echo Resultado: !RESULT!
)
Casos típicos que requieren expansión retardada
Numerar nombres de archivo
@echo off
setlocal enabledelayedexpansion
set NUM=0
for /f "delims=" %%f in ('dir /b /a-d *.jpg') do (
set /a NUM+=1
set PADDED=00!NUM!
set PADDED=!PADDED:~-3!
ren "%%f" "photo_!PADDED!.jpg"
)
echo Cambio de nombres finalizado.
endlocal
Si renombras archivos dentro de for %%f in (*.jpg), el bucle puede volver a procesar los archivos ya renombrados. Leer la salida de dir /b con for /f recorre la lista tal como estaba antes de empezar el bucle, lo que es más seguro.
Acumular valores en una variable
@echo off
setlocal enabledelayedexpansion
set ALL_FILES=
for %%f in (*.txt) do (
set ALL_FILES=!ALL_FILES! %%f
)
echo Archivos encontrados:!ALL_FILES!
endlocal
Aspectos a tener en cuenta
Cadenas que contienen un signo de exclamación !
Con la expansión retardada activada, el ! de una cadena se interpreta como delimitador de variable. Ten cuidado con nombres de archivo y rutas que contengan !.
rem Con la expansión retardada activada, se pierde el "!" y se muestra C:\ImportantFiles
set PATH_WITH_BANG=C:\Important!Files
echo !PATH_WITH_BANG!
Con la expansión retardada activada, las cadenas que contienen ! pueden expandirse de forma inesperada. Si necesitas manejar este tipo de rutas, desactiva la expansión retardada en esa parte con setlocal disabledelayedexpansion o escapa el carácter como ^^!.
Úsala solo donde haga falta
La expansión retardada es potente, pero no se necesita en todas partes. Para referencias simples fuera de bloques, usa el %variable% habitual.
Resumen
| Elemento | Detalle |
|---|---|
| Cómo activarla | setlocal enabledelayedexpansion |
| Sintaxis de referencia | !nombre_de_variable! |
| Dónde aparece el problema | Dentro de bucles FOR y bloques IF |
| Precaución | Las cadenas con ! pueden interpretarse mal |
La expansión retardada es un conocimiento imprescindible para manejar variables correctamente dentro de bucles y bloques en archivos por lotes.