可變替代
與其他程式語言不同,在批處理檔案中,在執行批處理指令碼之前,變數將由其實際值替換。換句話說,當命令處理器將指令碼讀入記憶體時,而不是稍後執行指令碼時,將進行替換。
這使得變數可以作為指令碼中的命令使用,也可以作為指令碼中其他變數名稱的一部分使用。此上下文中的指令碼是程式碼的行或塊,用圓括號括起來:()
。
但是這種行為確實意味著你無法在塊內更改變數的值!
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
。因此,每次通過時,回顯到螢幕的字串都會改變。