可變替代

與其他程式語言不同,在批處理檔案中,在執行批處理指令碼之前,變數將由其實際值替換。換句話說,當命令處理器將指令碼入記憶體時,而不是稍後執行指令碼時,將進行替換。

這使得變數可以作為指令碼中的命令使用,也可以作為指令碼中其他變數名稱的一部分使用。此上下文中的指令碼是程式碼的行或塊,用圓括號括起來:()

但是這種行為確實意味著你無法在塊內更改變數的值!

SET VAR=Hello
FOR /L %%a in (1,1,2) do (
    ECHO %VAR%
    SET VAR=Goodbye
)

將列印

Hello
Hello

因為(如你所見,在觀察命令視窗中執行的指令碼時),它被評估為:

SET VAR=Hello
FOR /L %%a in (1,1,2) do (
    echo Hello
    SET VAR=Goodbye
)

在上面的示例中,當指令碼被讀入記憶體時,ECHO 命令被評估為 Hello,因此指令碼將永遠回顯 Hello,但是通過指令碼進行了多次傳遞。

實現更傳統變數行為(在指令碼執行時擴充套件變數)的方法是啟用延遲擴充套件。這涉及在迴圈指令之前將該命令新增到指令碼中(通常是 FOR 迴圈,在批處理指令碼中),並在變數名稱中使用感嘆號(!)而不是百分號(%):

setlocal enabledelayedexpansion 
SET VAR=Hello
FOR /L %%a in (1,1,2) do (
    echo !VAR!
    SET VAR=Goodbye
)
endlocal

將列印

Hello
Goodbye

語法%%a in (1,1,2) 使迴圈執行 2 次:第一次,變數承載其初始值’Hello’,但是在第二次迴圈中迴圈 - 執行第二個 SET 指令作為第一次傳遞的最後一個動作 - 這已經改為修改後的值’Goodbye’。

高階變數替換

現在,一種先進的技術。使用 CALL 命令允許批處理命令處理器擴充套件位於指令碼同一行的變數。通過重複使用 CALL 和修飾符,可以實現多級擴充套件。

這在例如 FOR 迴圈中很有用。如下例所示,我們有一個編號的變數列表:

"c:\MyFiles\test1.txt" "c:\MyFiles\test2.txt" "c:\MyFiles\test3.txt"

我們可以使用以下 FOR 迴圈實現此目的:

setlocal enabledelayedexpansion
for %%x in (%*) do (
    set /a "i+=1"
    call set path!i!=%%~!i!
    call echo %%path!i!%%
)
endlocal

輸出:

c:\MyFiles\test1.txt
c:\MyFiles\test2.txt
c:\MyFiles\test3.txt

請注意,變數 !i! 首先擴充套件到其初始值 1,然後生成的變數%1 擴充套件到其實際值 c:\MyFiles\test1.txt。這是變數 i雙重擴充套件。在下一行,i 再次雙重展開,使用 CALL ECHO 命令和%%變數字首,然後列印到螢幕上(即顯示在螢幕上)。

在每次連續通過迴圈時,初始數量增加 1(由於程式碼 i+=1)。因此,它在第二次通過環路時增加到 2,在第三次通過時增加到 3。因此,每次通過時,回顯到螢幕的字串都會改變。