[英]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.