trato de evitar el uso de SETLOCAL enabledelayedexpansion ... ENDLOCAL
todas (o casi todas) las veces, porque por lo general quiero establecer o modificar algunas variables y quiero que los nuevos valores que estén disponibles en otras áreas de la secuencia de comandos o después de la finaliza el script por lotes (SETLOCAL | ENDLOCAL se olvidará de las nuevas variables o cambios en las variables en la parte "SETLOCAL" del script. Algunas veces es útil, pero para mí no suele ser así.
Actualmente uso el método descrito por @Zuzel, pero antes de saber sobre ese método, solía usar esto, que es muy similar (pero parece un poco más complicado):
for /F "usebackq delims=" %%f in (`echo set "a=^%a:%b%=%c%^%"`) do @%%f
script de ejemplo:
@echo off
set a=The fat cat
set b=fat
set c=thin
@echo.
@echo before: "%a%"
@echo replace "%b%" with "%c%" in "%a%" using for:
for /F "usebackq delims=" %%f in (`echo set "a=%%a:%b%=%c%%%"`) do @%%f
@echo after for: "%a%"
goto :EOF
la salida de la ejecución del script:
before: "The fat cat"
replace "fat" with "thin" in "The fat cat" using for:
after for: "The thin cat"
me gusta este método porque se puede llamar a programas externos (o comandos internos) usando variables modificadas y también capturar y procesar la salida del comando (línea por línea).
Pero, el método de Zuzel es más simple y más limpio para la mayoría de las situaciones, incluida la que usted describió.
Nota:
Ambos métodos (y también SETLOCAL enabledelayedexpansion ... ENDLOCAL
, por supuesto), sólo funcionan correctamente si se ejecuta desde dentro de un archivo por lotes. Si intenta utilizar cualquiera de estos dos métodos ("llamar" o "para") directamente en una ventana del símbolo del sistema, obtendrá algo diferente de lo que se estaba ejecutando desde un script.
Por ejemplo, ejecutar esto como una secuencia de comandos:
@echo off
set a=The fat cat
set b=fat
set c=thin
set d=calico
set e=sleepy
@echo.
@echo before: "%a%"
@echo.
@echo replace "%b%" with "%c%" in "%a%" using call:
call set a=%%a:%b%=%c%%%
@echo after call: "%a%" ("%b%" to "%c%")
@echo.
@echo replace "%c%" with "%d%" in "%a%" using for:
for /F "usebackq delims=" %%f in (`echo set "a=%%a:%c%=%d%%%"`) do @%%f
@echo after for: "%a%" ("%c%" to "%d%")
@echo.
@echo replace "%d%" with "%e%" in "%a%" using call:
call set a=%%a:%d%=%e%%%
@echo after call: "%a%" ("%d%" to "%e%")
la salida de la ejecución del script:
before: "The fat cat"
replace "fat" with "thin" in "The fat cat" using call:
after call: "The thin cat" ("fat" to "thin")
replace "thin" with "calico" in "The thin cat" using for:
after for: "The calico cat" ("thin" to "calico")
replace "calico" with "sleepy" in "The calico cat" using call:
after call: "The sleepy cat" ("calico" to "sleepy")
Ahora, ejecute los comandos directamente en un símbolo del sistema ventana:
c:\>
c:\>set a=The fat cat
c:\>set b=fat
c:\>set c=thin
c:\>set d=calico
c:\>set e=sleepy
c:\>
c:\>@echo.
c:\>@echo before: "%a%"
before: "The fat cat"
c:\>@echo.
c:\>
c:\>@echo replace "%b%" with "%c%" in "%a%" using call:
replace "fat" with "thin" in "The fat cat" using call:
c:\>call set a=%%a:%b%=%c%%%
c:\>@echo after call: "%a%" ("%b%" to "%c%")
after call: "%The thin cat%" ("fat" to "thin")
c:\>
c:\>@echo.
c:\>@echo replace "%c%" with "%d%" in "%a%" using for:
replace "thin" with "calico" in "%The thin cat%" using for:
c:\>for /F "usebackq delims=" %f in (`echo set "a=%%a:%c%=%d%%%"`) do @%f
c:\>@echo after for: "%a%" ("%c%" to "%d%")
after for: "%%The calico cat%%" ("thin" to "calico")
c:\>
c:\>@echo.
c:\>@echo replace "%d%" with "%e%" in "%a%" using call:
replace "calico" with "sleepy" in "%%The calico cat%%" using call:
c:\>call set a=%%a:%d%=%e%%%
c:\>@echo after call: "%a%" ("%d%" to "%e%")
after call: "%%%The sleepy cat%%%" ("calico" to "sleepy")
c:\>
examine las líneas de salida antes y después desde la ventana del símbolo del sistema:
before: "The fat cat"
replace "fat" with "thin" in "The fat cat" using call:
after call: "%The thin cat%" ("fat" to "thin")
replace "thin" with "calico" in "%The thin cat%" using for:
after for: "%%The calico cat%%" ("thin" to "calico")
replace "calico" with "sleepy" in "%%The calico cat%%" using call:
after call: "%%%The sleepy cat%%%" ("calico" to "sleepy")
Observe que las sustituciones se realizan correctamente, pero también observe que al ejecutar estos comandos directamente en la ventana del símbolo del sistema, agrega un conjunto de "%" (signos de porcentaje) antes y después del valor esperado cada vez la sustitución está hecha. Por lo tanto, hace que sea difícil probar cualquiera de estos métodos directamente en la ventana del símbolo del sistema.
Yo esperaría que este comportamiento, pero también me esperar alguna forma de retrasar la expansión o 'anidar' la expansión. Por cierto, estoy de acuerdo, nada es fácil, ni inmediatamente obvio en DOS. – GKelly