Tengo este script por lotes que hojea 5 variables de conjunto estático que contienen una ruta de archivo a un INI
archivo que luego lee y busca una cadena específica para reemplazar.
Mi problema es que después de realizar dichos reemplazos y escribir el archivo nuevamente en el disco, parece estar desinfectando todas las instancias dentro !
del archivo INI, lo que a su vez rompe mi programa.
Supongo que las !
marcas se están reemplazando debido a DelayedExpansion pero las necesito para realizar mis tareas aquí. Incluyo una copia de la función con el problema. Le agradecería mucho que alguien pudiera ayudarme a resolver esto.
He estado atrapado tratando de encontrar una respuesta a esto desde hace días...
FOR %%A IN (1 2 3 4 5) DO (
SET CFG_A=!CFG_%%A!
IF "%DEBUG%"=="1" ECHO !CFG_A!
FOR /f "delims=" %%i IN ('type "!CFG_A!" ^& break ^> "!CFG_A!" ') DO (
SET "line=%%i"
SETLOCAL enabledelayedexpansion
SET "line=!line:%IP_V%=%IP%!"
>>"!CFG_A!" echo(!line!
ENDLOCAL
)
)
Respuesta1
Obviamente, ha retrasado la expansión en todo el código publicado, y la expansión retrasada se produce después de la expansión variable FOR. Entonces sí, el valor de %%i
está dañado porque la expansión retrasada está habilitada.
Una solución es colocar un SETLOCAL/ENDLOCAL adicional dentro de su bucle interno para deshabilitar temporalmente la expansión retrasada mientras %%i
se expande.
Además, no es necesario ESCRIBIR el archivo, ni el extraño BREAK redirigido para crear un archivo de salida vacío, ni la redirección adjunta dentro del bucle. Simplemente puede dejar que FOR /F lea el archivo directamente y redirigirlo una vez fuera del bucle interno. Por supuesto, debe escribir en un nuevo archivo temporal y luego mover el resultado al nombre original. Pero esto es mucho más eficiente (más rápido).
FOR %%A IN (1 2 3 4 5) DO (
IF "%DEBUG%"=="1" >&2 ECHO(!CFG_%%A!
(FOR /f "usebackq delims=" %%i IN ("!CFG_%%A!") DO (
SETLOCAL disableDelayedExpansion
SET "line=%%i"
SETLOCAL enableDelayedExpansion
SET "line=!line:%IP_V%=%IP%!"
echo(!line!
ENDLOCAL
ENDLOCAL
))>"!CFG_%%A!.new"
MOVE /Y "!CFG_%%A!.new" "!CFG_%%A!" >nul
)
Nota: Realmente no me gusta editar archivos de texto por lotes. En lugar de eso, usaríaJREPL.BAT: una utilidad híbrida JScript/batch que se ejecuta de forma nativa en cualquier máquina con Windows desde XP en adelante:
FOR %%A IN (1 2 3 4 5) DO CALL JREPL "%IP_V%" "%IP%" /L /I /F "!CFG_%%A!" /O -
Mucho más sencillo, más rápido y más fiable :-)