Проблеми із затримкою розширення та змінною заміною


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

Ви, очевидно, затримали розширення протягом усього розміщеного коду, а затримка розширення виникає після змінного розширення. Так, так, значення %%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 / пакетної версії, яка працює на будь-якій машині Windows від XP далі :

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

Набагато простіше, швидше і надійніше :-)


Це вийшло справді добре! Велике спасибі! Я зміг застосувати його до свого коду, і я також чітко розумію, чому ти зробив те, що робив. Щодо питань, що стосуються використання "перерви", я мушу визнати, що навіть я цього не повністю зрозумів. Мені знайшов рішення для цього мій друг і моє основне розуміння цього після того, як витратив багато часу на те, щоб возитися з ним, це те, що він редагує дані в пам'яті, а потім записує їх у файл, але я не впевнений.
Pyr3x

Дейв - Коли ви отримаєте шанс, на всякий випадок у вас є якісь поради по темі з цим питанням "Моє запитання", я хотів би надіслати вам посилання на всякий випадок. Для цього, крім того, що вже говорили інші, може бути не багато, але я подумав, що якщо хтось матиме якісь корисні поради, то це ви будете. Продовжуйте свою велику роботу, чоловіче !!
Pimp Juice IT
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.