2012-11-03 110 views
0
@echo off 
cd %~dp0 
md .\newfolder 
for /f "usebackq delims=" %%f in ("list.txt") do (
    call set /a add=%%add%%+1 
    call set addx=0000%%add%% 
    call set addx=%%addx:~-3%% 
    call copy "%%f" ".\newfolder\%%addx%%_%%f" 
) 
pause 

我做了簡單的namechange代碼。我通常使用不帶'call'的命令,但是在這裏它會產生錯誤信息。這是爲什麼? ..當我使用%變量%不是%%變量%%,它不工作.. plz告訴我爲什麼會發生..和最後一個問題..環境變量的值被存儲,直到退出cmd。我想知道我怎麼可以不設置的..謝謝..批處理命令有什麼不同?

回答

1

帶括號的塊內的所有代碼在一個通被解析。在解析時發生使用百分比的正常變量擴展。因此,如果在塊中設置變量,則無法使用正常擴展訪問該值,因爲該值將是您輸入塊之前存在的值。

您有上述情況。有兩種經典的方法來解決這個問題。

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放在靠近頂部的位置,這樣環境變量定義在批處理文件完成後不會持續。

+0

你是天才謝謝 – dskim

+0

我從哪裏可以得到關於它的更多信息? ..我是一個初學者。不習慣英語,所以很難理解.. – dskim