延遲擴展和變數替換問題

延遲擴展和變數替換問題

我有這個批次腳本,它會翻轉 5 個靜態設定變量,其中包含檔案的檔案路徑INI,然後讀取並蒐索要替換的特定字串。

我的問題是,在 if 執行上述替換並將檔案寫回磁碟之後,它似乎正在清理!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

顯然,您在整個發布的程式碼中都延遲了擴展,並且延遲擴展發生在 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/批次實用程序,可在 XP 及以上的任何 Windows 電腦上本機運行:

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

更簡單、更快、更可靠:-)

相關內容