簡體   English   中英

遍歷文件並僅在使用批處理文件的zip文件夾中解壓縮

[英]Iterating through the files and extracting only if its a zip folder using a batch file

我需要遍歷當前文件夾中的所有文件,並僅在其為zip文件時提取它們。 所以我寫了下面的批處理腳本。 但是我說錯了

"=="."zip" was unexpected at this time

下面是我編寫的批處理腳本。

@echo off
cd /d %~dp0
for /r %%i in (*) do if %%i "%Extension%"==".zip" (
setlocal
cd /d %~dp0
Call :UnZipFile "G:\NewUpdates\ExtractedStuff" %%i
exit /b

:UnZipFile <ExtractTo> <newzipfile>
set vbs="%temp%\_.vbs"
if exist %vbs% del /f /q %vbs%
>%vbs%  echo Set fso = CreateObject("Scripting.FileSystemObject")
>>%vbs% echo If NOT fso.FolderExists(%1) Then
>>%vbs% echo fso.CreateFolder(%1)
>>%vbs% echo End If
>>%vbs% echo set objShell = CreateObject("Shell.Application")
>>%vbs% echo set FilesInZip=objShell.NameSpace(%2).items
>>%vbs% echo objShell.NameSpace(%1).CopyHere(FilesInZip)
>>%vbs% echo Set fso = Nothing
>>%vbs% echo Set objShell = Nothing
cscript //nologo %vbs%
if exist %vbs% del /f /q %vbs%
)
pause

我在這里做錯了什么? 請指教。

您正在讀取未定義的變量%Extension% ,並且if語句中==的左側有兩個表達式,這是一個語法錯誤。

要獲取由for循環迭代的項的文件擴展名,請使用~x修飾符(在命令提示符下鍵入for /?以獲得更多信息),例如代碼中的%%~xi

if /i "%%~xi"==".zip" ( ... )

/i開關使比較不區分大小寫,在這里推薦這樣做,因為Windows以相同的方式對待文件名。


然而,在你的情況,你不需要if語句在所有檢查的文件擴展名,因為你可以讓for做的工作:

for /r %%i in (*.zip) do ( ... )

此循環僅遍歷*.zip文件。


您的代碼中還有另一個問題:子例程:UnZipFile是循環主體的一部分,因此在循環內部存在並exit /b

子例程必須在循環之外。 call執行,代碼parenthesised塊的當前環境不會在子程序已知的,所以它不會被認為是一旦循環結束結束)出現,而是一個語法錯誤發生。 因此,您需要將)從最底部移至新行, 然后 exit /b (如果將其放置在后面,則exit命令將中斷循環)。

由於您在循環內設置了setlocal ,因此還需要將endlocal放置在( )之前,以便不超過setlocal嵌套限制。 但是,如果在循環內部使用完整路徑,則不需要setlocal / endlocal 相反,我將setlocal / endlocal移到子例程中以本地化其中使用的環境變量。


我不確定您是否打算更改為cd /d %~dp0存放腳本的目錄,但是我認為您想在循環中獲取當前迭代的*.zip文件的完整路徑,對嗎? 如果是這樣,請刪除cd命令,然后在call命令行中使用%%~fi


最后,在整個代碼中引用並不是最優的。 例如,總是引用文件路徑和名稱是一個好主意,因為它們可能包含空格或一些其他字符,這些字符被命令解釋器視為定界符或對其具有其他特殊含義。

同樣在子例程中,您應該引用作為參數提供的路徑,並以"%~1"訪問它們,例如,使其正確地被引用(鍵入call /?可以看到~刪除了由有意提供的周圍引號。命令行)。

最好的set語法是: set "vbs=%temp%\\_.vbs" ; 因此,引號不會成為值的一部分,並且您總是在一個地方放置引號-即在讀取 (擴展)變量時,例如"%vbs%"


最后,讓我建議您使用縮進,以使代碼更加清晰易維護。


這是固定代碼:

@echo off
cd /d %~dp0
for /r %%i in ("*.zip") do (
    Call :UnZipFile "G:\NewUpdates\ExtractedStuff" "%%~fi"
)
exit /b

:UnZipFile <ExtractTo> <newzipfile>
    setlocal
    set vbs="%temp%\_.vbs"
    if exist "%vbs%" del /f /q "%vbs%"
     >"%vbs%" echo Set fso = CreateObject("Scripting.FileSystemObject")
    >>"%vbs%" echo If NOT fso.FolderExists("%~1") Then
    >>"%vbs%" echo fso.CreateFolder("%~1")
    >>"%vbs%" echo End If
    >>"%vbs%" echo set objShell = CreateObject("Shell.Application")
    >>"%vbs%" echo set FilesInZip=objShell.NameSpace("%~2").items
    >>"%vbs%" echo objShell.NameSpace("%~1").CopyHere(FilesInZip)
    >>"%vbs%" echo Set fso = Nothing
    >>"%vbs%" echo Set objShell = Nothing
    cscript //nologo "%vbs%"
    if exist "%vbs%" del /f /q "%vbs%"
    endlocal
    pause

我的建議是通過在for命令中過濾zip文件來簡化搜索,而不是檢查文件擴展名

使用以下命令:

for /f "tokens=*" %%a in ('dir /a:-d /b ^| findstr /r ".zip$"') do echo %%a

上面的命令將列出目錄中的所有zip文件,現在您可以按照自己的方式播放它們了

希望這可以幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM