帶括號的塊內的所有代碼在一個通被解析。在解析時發生使用百分比的正常變量擴展。因此,如果在塊中設置變量,則無法使用正常擴展訪問該值,因爲該值將是您輸入塊之前存在的值。
您有上述情況。有兩種經典的方法來解決這個問題。
1)您可以使用電話和你做了雙倍的百分比。 CALL解決了這個問題,因爲對於一個被調用的行來說,正常的擴展會發生兩次 - 一次是整個塊,另一次是在執行該行之前,但在該塊中之前的行已經執行之後。第一次擴展將雙重百分比轉換爲單一百分比,第二次擴展實際上擴展了變量。
我不喜歡這個解決方案,因爲它很慢,並且還因爲CALL導致引用^
字符的問題 - 它們翻倍。
您可以在同一命令上使用多個CALL。每次通話都要求百分比翻倍。所以一個CALL要求2個百分數,兩個呼叫需要4個perecents,三個電話8個百分比,等等
2)我認爲優選的解決方案是使用延遲擴展。它的速度要快得多,而且你永遠不必擔心逃跑或當您使用延遲擴展引用特殊字符,如&
,|
,>
,<
等。延遲擴展就像它所說的那樣 - 直到線被執行之前變量才被擴展。延遲擴展必須先啓用才能使用。在批處理文件中,您可以使用setlocal enableDelayedExpansion
。
可以用延遲擴展會出現一個問題是,如果它們含有!
變量被破壞,當他們被擴展延遲擴充被啓用。這通常可以通過在循環中切換延遲擴展和關閉來解決。
如果您在命令提示符下鍵入HELP SET
,你會得到這個問題的一個很好的描述有一個代碼塊中擴大變量,以及如何擴展延遲可以提供幫助。描述開始大約半路,用Finally, support for delayed environment variable expansion...
。
注 - 在SET/A計算中使用時不需要展開變量。 SET/A將在執行時自動擴展該值。未定義的變量被視爲零。
在你的代碼,你可以簡單地使用set /a add=add+1
但還有一個更簡單的簡寫方式 - 你可以使用+=
操作:set /a add+=1
。
這是另一種方式,您的代碼可以不使用CALL編寫。代碼沒有經過測試,但我認爲我是對的。
@echo off
setlocal disableDelayedExpansion
cd "%~dp0"
md newfolder
set add=0
for /f "usebackq eol=: delims=" %%F in ("list.txt") do (
set /a add+=1
set "file=%%F"
setlocal enableDelayedExpansion
set "addx=00!add!"
copy "!file!" "newfolder\!addx:~-3!_!file!"
endlocal
)
pause
我明確地將add
初始化爲0,因爲它可能已經被設置爲一個值。如果您知道它未定義或已設置爲0,則不需要初始化。
您的FOR循環處理文件名,並且!
在文件名中有效。這就是我在循環中開啓和關閉延遲擴展的原因 - 當我擴展%%F
時,我不希望!
文件名被破壞。文件名也可以從;
開始(儘管極不可能)。如果是這樣,那麼FOR將跳過該文件,因爲默認的EOL字符是;
。一個文件永遠不能以:
開頭,所以我想將EOL設置爲:
。
我把SETLOCAL放在靠近頂部的位置,這樣環境變量定義在批處理文件完成後不會持續。
你是天才謝謝 – dskim
我從哪裏可以得到關於它的更多信息? ..我是一個初學者。不習慣英語,所以很難理解.. – dskim