2

У меня есть этот пакетный скрипт, который пролистывает 5 статических переменных набора, содержащих путь к файлу INI который он затем читает и ищет конкретную строку для замены.

Моя проблема заключается в том, что после выполнения указанных замен и записи файла обратно на диск он, похоже, очищает все экземпляры ! в файле INI, который в свою очередь нарушает мою программу.

Я угадываю ! метки заменяются из-за DelayedExpansion, но мне это нужно для выполнения моих задач здесь. Я включаю копию функции в проблему, я был бы очень признателен, если бы кто-то мог помочь мне разобраться в этом.

Я застрял, пытаясь найти ответ на этот вопрос в течение нескольких дней ...

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
    )
)

1 ответ1

1

Вы, очевидно, задержали расширение во всем размещенном коде, и задержка произошла после расширения переменной FOR. Так что да, значение %%i повреждено, потому что включено отложенное расширение.

Одно из решений состоит в том, чтобы поместить дополнительный SETLOCAL / ENDLOCAL во внутренний цикл, чтобы временно отключить отложенное расширение, пока %%i расширяется.

Кроме того, нет необходимости в ТИПЕ файла, и нет необходимости в нечетном перенаправленном BREAK для создания пустого выходного файла или добавления перенаправления в цикле. Вы можете просто позволить FOR /F читать файл напрямую и перенаправлять один раз за пределы внутреннего цикла. Конечно, вы должны записать во временный новый файл, а затем переместить результат в исходное имя. Но это гораздо эффективнее (быстрее).

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
)

Примечание. Мне действительно не нравится редактировать текстовые файлы с помощью пакета. Вместо этого я бы использовал JREPL.BAT - гибридную утилиту JScript/batch, которая изначально работает на любом компьютере с Windows начиная с XP:

FOR %%A IN (1 2 3 4 5) DO CALL JREPL "%IP_V%" "%IP%" /L /I /F "!CFG_%%A!" /O -

Намного проще, быстрее и надежнее :-)

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .