2015-10-15 55 views
0

我當前正在創建一個批處理文件,該文件解壓縮它將在指定文件夾中檢測到的所有存檔。現在我想使用此代碼的指定文件夾內檢測存檔文件:批處理文件忽略FOR循環內的ELSE語句

@ECHO OFF 
SETLOCAL 
SETLOCAL EnableDelayedExpansion 

SET quote=" 
SET cwdText=Current working directory: 
SET cwd=%cd% 
SET fullCWD=%cwdText%%cwd% 
SET path=%~dp0 
SET types=file_types.txt 
SET fullPath=%path%%types% 

ECHO %fullCWD% 
ECHO %fullPath% 

:SPECIFYPATH 
ECHO: 
SET /P directory=Specify the full path location of the archive files: 

IF "%cd%"=="%directory%" (
ECHO Specified location is already the current directory 
GOTO SPECIFYPATH 
) ELSE (
PUSHD %directory% 
CD 
GOTO CHECKARCHIVES 
) 

:CHECKARCHIVES 
FOR %%T IN (*.zip,*.rar,*.7z) DO (
IF EXIST %%T (
    ECHO Archive files detected 
    GOTO EOF 
) ELSE (
    ECHO Archive files not detected 
    GOTO EOF 
) 
GOTO EOF 
) 

:EXTRACT 
ECHO Extracting archive files 

:EOF 
PAUSE 

其中,我開始檢查歸檔文件的部分是在:CHECKARCHIVES標籤。我現在遇到的問題是每當我嘗試指定一個沒有存檔文件的文件夾時,代碼立即跳轉到:EXTRACT標籤,並且不會轉到FOR語句中的ELSE語句。有人可以解釋爲什麼這樣嗎?

我也試過在第一個IF聲明後面使用IF NOT EXIST...聲明,但我仍然得到相同的行爲。

回答

4

當正由所述for命令列舉的元素不包含一個通配符,所述do子句中的代碼被執行並且for替換參數將包含元件原樣。

但是,當枚舉元素包含通配符時,假定需要擴展它,並檢查文件系統是否存在匹配通配符表達式的文件。如果沒有匹配的文件,則do子句中的代碼不會爲此元素執行。如果有與該表達式匹配的文件,則do子句中的代碼不會執行表達式,而會執行每個匹配文件,並且for可替換參數將保存對當前引用的引用。

當你的代碼,如果有匹配的文件使用通配符時,do子句中的代碼是爲每個文件(僅適用於發現,因爲goto的第一個文件,你的情況)執行,並且,如果沒有任何匹配的文件,do子句中的代碼不會執行,因此無法訪問else子句。

但是,假設for不會檢查文件系統,並且指示的元素按寫入的方式迭代。你將會有一個邏輯錯誤。內部if命令將檢查是否存在僅匹配第一組的文件。如果找不到與第一組文件相匹配的文件,則您將for命令與goto保留在else子句中,因此,其餘組不會被檢查。

爲了保持for檢查文件是否存在更好的方法可能是

for %%T in (*.zip, *.rar, *.7z) do goto :extract 
echo No archives found 
goto eof 

若出現任何文件,匹配任何通配符表達式,發現那麼goto將取消當前枚舉,並跳轉到您的:extract標籤。如果for循環結束並且到達下一行,那是因爲沒有找到匹配的文件。

+0

我明白了。所以這意味着批處理文件環境中的'FOR'語句更像是一個'IF'語句的迭代版本,而不像我們通常在C++等編程語言中知道的那樣? – Jairo

+0

我不會說迭代'if';你可以認爲它像'for each',遍歷所有匹配的文件... – aschipfl

+0

@Jairo,'for'只是[*「globs」*](https://en.wikipedia.org/wiki/Glob_% 28編程%29)指定組中的元素。 –

1

這是您顯示的代碼的正確行爲。如果沒有檔案文件,則不會輸入'DO'構造。你可以做這樣的事情,或者更好的是在進入循環之前將計數器清零並在循環中增加它......然後在循環之外詢問它是否需要計數文件。

SET "Msg=Archive files not detected" 
FOR %%T IN (*.zip,*.rar,*.7z) DO (
    SET "Msg=Archive files detected" 
    REM do something else as needed 
) 
ECHO %Msg% 
+0

是不是行'SET'Msg =沒有檢測到存檔文件「'沒有使用'IF'語句,將觸發它和'FOR'循環語句?如果我問這個,我很抱歉。這是我第一次開發批處理文件。 另一個我曾經想過的問題是,如果我使用我的代碼,並且您建議的是我可能會添加ZIP,RAR和7z以外的其他存檔文件類型。有沒有辦法讓我做到這一點?我正在考慮使用一個文本文件,其中列舉了所有的歸檔文件類型,並使用該文件檢查目錄/文件夾中是否存在任何文件。 – Jairo

+0

1.不,它不是無用的,它預先初始化'Msg';如果遇到檔案文件,'for'koop正在迭代,'Msg'被更新/覆蓋; 2.關於檔案類型列表:通過評論擴展原始問題的範圍並不是一個好主意;相反,你應該發表一個新的問題,涵蓋... – aschipfl

+0

@aschipfl我明白。關於我的其他問題,我會發佈一個新問題。 – Jairo

0

此外RGuggisberg的帖子,你可以隨時檢查文件中像這樣用不同的語法for-loop之外。

for %%t in (*.zip,*.rar,*.7z) do set "myvar=%%t" 
if defined myvar (echo msg#1 Archive files DETECTED) else (echo msg#1 Archive files NOT detected) 

for %%t in (*.zip,*.rar,*.7z) do (
    set "myvar=%%t" 
) 
if defined myvar (echo msg#2 Archive files DETECTED) else (echo msg#2 Archive files NOT detected) 

rem check the myvar by negation 
if NOT defined myvar (echo msg#3 Archive files NOT detected) else (echo msg#3 Archive files DETECTED)