Problemas de expansión retrasada y reemplazo de variables

Problemas de expansión retrasada y reemplazo de variables

Tengo este script por lotes que hojea 5 variables de conjunto estático que contienen una ruta de archivo a un INIarchivo 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 %%iestá 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 %%ise 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 :-)

información relacionada