我需要遍历当前文件夹中的所有文件,并仅在其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
我在这里做错了什么?请指教。
答案 0 :(得分:1)
您正在读取未定义的变量%Extension%
,并且==
语句中if
左侧有两个表达式,这是语法错误。
要获取由for
循环迭代的项的文件扩展名,请使用~x
修饰符(在命令提示符下键入for /?
以查找更多相关内容),例如{您的代码中的{1}}:
%%~xi
if /i "%%~xi"==".zip" ( ... )
开关使比较不区分大小写,这是建议使用的,因为Windows会以相同的方式处理文件名。
但是,在您的情况下,您根本不需要/i
语句来检查文件扩展名,因为您可以让if
完成这项工作:
for
此循环仅遍历for /r %%i in (*.zip) do ( ... )
个文件。
您的代码中还有另一个问题:子例程*.zip
是循环体的一部分,因此循环内部有:UnZipFile
。
子程序必须在循环之外。执行exit /b
时,子例程中不知道带括号的代码块的当前上下文,因此一旦出现循环结束call
,它就不会被视为结束,而是语法出现错误。因此,您需要在 )
之前将)
从最底部移动到新行(如果您放置它,exit /b
命令将打破循环)。
由于您的循环中有exit
,因此您还需要setlocal
(紧靠endlocal
之前),以便不超过)
嵌套限制。但是,如果您在循环内部使用完整路径,则不需要setlocal
/ setlocal
。相反,我会将endlocal
/ setlocal
移动到子例程中,以本地化其中使用的环境变量。
我不确定您是否打算更改为endlocal
存储脚本的目录,但我认为您需要循环中当前迭代的cd /d %~dp0
文件的完整路径, ?如果是,请删除*.zip
命令并在cd
命令行中使用%%~fi
。
最后,引用在整个代码中并不是最佳的。例如,引用文件路径和名称总是一个好主意,因为它们可能包含空格或一些其他字符,这些字符被命令解释器视为分隔符,或者具有其他一些特殊含义。
同样在子例程中,您应引用作为参数提供的路径,并将其作为call
访问,以便正确引用它们(键入"%~1"
以查看{{1}删除命令行可能提供的周围引号。
最好的call /?
语法是:~
;因此引号不会成为值的一部分,并且您总是一个来放置引号 - 即读取(扩展)变量时,如{{1} }。
最后,让我建议您使用缩进,以便代码变得更易读和可维护。
这是固定代码:
set
答案 1 :(得分:0)
我的建议是通过在for命令中过滤来简化对zip文件的搜索,而不是检查文件扩展名
使用以下命令:
for /f "tokens=*" %%a in ('dir /a:-d /b ^| findstr /r ".zip$"') do echo %%a
以上命令将列出目录中的所有zip文件,现在您可以按照自己的方式使用它们
希望这会有所帮助。