您的代碼的主要問題是變量擴展。在批處理文件中,當一個命令或一個命令塊(包含在括號中的幾個命令)被獲得時,它們被解析並執行。在解析階段,變量讀取操作(%var%
)將從代碼中被替換爲變量內部的值。一旦完成,命令或塊就會執行。所有這一切意味着當執行代碼時,如果更改變量(代碼中的exists
),則在同一個命令/塊內部無法檢索更改後的值,因爲沒有任何變量讀取操作,只有在開始執行階段之前變量中的值。
這可以使用setlocal enabledelayedexpansion
避免。此命令允許您將需要的語法從%var%
更改爲!var!
,指示解析器必須延遲變量擴展直到命令執行,而不是在解析階段。
所以,你的代碼可能是像
@echo off
setlocal enabledelayedexpansion
cls
cd test
for %%f in (*.*) do (
set "exist=false"
for %%a in (%*) do (
if /i "%%~xf" == ".%%a" set "exist=true"
if /i "%%~xf" == ".sys" set "exist=true"
)
if "!exist!"=="false" (
del "%%f"
)
)
pause
注意
set var = value
已改爲set var=value
。空格很重要,你定義了一個變量var[space]
,其值爲[space]value
所有變量賦值都被引用以防止包含在變量值中的不需要的結束空格。如果包含空格,==
測試可能會失敗。小心這是不需要的,但這是一個好習慣。都被包括
引號,以防止與在文件名中的空格或擴展
的%exists%
已改變爲!exists!
如此改變的值可以被檢索問題的同時,相同的塊內(for %%f
)
if
擴展比較包括用於不區分大小寫測試的/i
開關。
你也應該注意到,當已延遲擴展啓用,!
性格變得解析器會認爲這是一個可變的讀取操作的一部分問題。如果您的文件或擴展名可能包含此字符,則延遲擴展是個問題。它可以完成但需要只在真正需要時啓用延遲擴展,並在不需要時再次禁用。
@echo off
setlocal disabledelayedexpansion
cls
cd test
for %%f in (*.*) do (
set "exist=false"
for %%a in (%*) do (
if /i "%%~xf" == ".%%a" set "exist=true"
if /i "%%~xf" == ".sys" set "exist=true"
)
setlocal enabledelayedexpansion
if "!exist!"=="false" (
endlocal
del "%%f"
) else (
endlocal
)
)
pause
但是,正如你的情況,你只更改兩個值,值是不相關的變量的值,它僅僅是一個標誌,你可以忽略延遲擴展和變量中的真正價值和使用替代語法if defined
來測試變量是否包含值。你true/false
可以是defined/not defined
測試
@echo off
setlocal enableextensions disabledelayedexpansion
cd test
for %%f in (*) do (
set "removeFile=1"
for %%x in (sys %*) do (
if /i "%%~xf"==".%%~x" set "removeFile="
)
if defined removeFile del "%%f"
)
pause
如果擴展匹配任何的參數,變量的內容被刪除,也就是現在的變量是不確定的。
編輯適應脫線的評論
當與filesytem元素處理,就可以看到這個文件/文件夾選擇意外行爲。
不遵循8.3
傳統命名的文件和文件夾(名稱最多8個字符,最多3個擴展名,無特殊字符,無空格)具有所謂的長名稱,但它們還有一個簡短的8.3
名稱與長名稱關聯。可以在dir
命令中使用/x
開關。
雖然不是直接可見,但是當完成通配符搜索時會檢查這些短名稱,從而導致選擇的文件/文件夾的長文件名或擴展名與所請求的通配符表達式不匹配,但名稱或擴展名與通配符匹配。
在需要的情況下內for
循環要處理的短名稱或擴展,在for
替換參數使用的改性劑(例如,%%f
)來檢索他們是
%%~snxf Short name and short extension of the element being referenced by %%f
%%~snf Short name of the element being referenced by %%f
%%~sxf Short extension of the element being referenced by %%f
確實很好。或許你應該加上關於lfn vs sfn的警告。 – Magoo
@Magoo,因爲代碼對於短文件名/擴展名沒有任何問題。搜索不是使用文件的擴展名來完成的,'%%〜xf'如果存在,它將檢索長擴展名。 –
@MCND哇!非常感謝,這是非常翔實的! – Igor