我有一个如下文件夹结构:
平面列表中的相同文件:
D:\folder\test1\test1.zip
D:\folder\test1\opt\test1.zip
D:\folder\test2\test2.zip
D:\folder\test2\opt\test2.zip
D:\folder\test3\test3.zip
D:\folder\test3\opt\test3.zip
我有一个优化zip文件的脚本。我在批处理文件中需要做的是基本上在opt
文件夹中找到这些优化文件,并用较小的文件覆盖较大版本。
答案 0 :(得分:0)
看看这个评论的批次代码:
@echo off
for /D %%I in ("D:\folder\*") do (
if exist "%%I\%%~nxI.zip" (
if exist "%%I\opt\%%~nxI.zip" (
call :CompareFiles "%%I\%%~nxI.zip" "%%I\opt\%%~nxI.zip"
)
)
)
goto :EOF
rem The loop runs on each subdirectory of directory D:\folder. It first
rem checks if there is a *.zip file in the subdirectory with same name as
rem the subdirectory. Next it checks if in the current subdirectory there
rem is a subdirectory with name "opt" with having also a *.zip file with
rem same name as the subdirectory. If this second condition is also true,
rem the subroutine CompareFiles is called with the names of the 2 ZIP files.
rem The subroutine compares the file size of the two ZIP files.
rem The optimized ZIP file is moved over the ZIP file in directory
rem above if being smaller than the ZIP file in directory above.
rem Otherwise the optimized ZIP file being equal or greater as the
rem ZIP file above is deleted.
rem Finally the subdirectory "opt" is deleted which works only if the
rem subdirectory is empty. The error message output by command RD in
rem case of "opt" is not empty is redirected from STDERR to device NUL
rem to suppress it.
rem goto :EOF above results in exiting processing this batch file after
rem finishing the loop and avoids a fall through to the subroutine. The
rem goto :EOF below would not be really necessary as it is at end of the
rem batch file. But it is recommended to end each subroutine with goto :EOF
rem or alternatively exit /B in case of one more subroutine is added later.
:CompareFiles
if %~z1 GTR %~z2 (
move /Y %2 %1
) else (
del /F %2
)
rd "%~dp2" 2>nul
goto :EOF
您可以通过在命令echo
和move
中插入命令del
来测试批处理文件,并在命令提示符窗口中运行批处理文件以查看输出。当结果符合预期时,再次运行批处理文件,而不添加两个echo
。
<强>注意:强>
Windows命令处理器仅支持带符号的32位整数。因此,此批处理代码不适用于具有2 GiB(= 2.147.483.650字节)或更多的ZIP文件。
%%~nxI
通常引用文件名和文件扩展名。 Windows命令处理器将最后一个反斜杠后的所有内容解释为文件或目录的名称。这里分配给循环变量I
的字符串是驱动器和路径D:\folder\
不以反斜杠结尾的子目录的名称。因此%%~nI
引用了D:\folder\
中当前子目录的名称。文件扩展名定义为最后一点之后的所有内容。目录通常没有目录名称中的点,因此%%~nI
通常也足以用于目录名称。但是也可以使用目录名中的一个点创建目录。因此,使用%%~nxI
比任何目录名更安全。
注意:命令 FOR 会忽略具有隐藏或系统属性的子目录。
在子例程%1
而不是%2
和CompareFiles
中仅使用"%~1"
和"%~2"
是100%安全的,因为两个文件名必须已经通过用子引号括起来包含空格或其中一个字符:&()[]{}^=;!'+,`~
。因此,从执行的角度来看,使用move
和del
在"%~1"
和"%~2"
上指定参数(文件名)是没有意义的。但是,当然可以使用"%~1"
和"%~2"
来更好地在文本编辑器中进行语法突出显示,或者使用作为参数传递给批处理文件或子例程的统一文件名引用。
如果两个ZIP文件完全存在且优化的ZIP文件非常小,则可以在不测试时简化批处理文件。
@echo off
for /D %%I in ("D:\folder\*") do (
move /Y "%%I\opt\%%~nxI.zip" "%%I\%%~nxI.zip" 2>nul
rd "%%I\opt" 2>nul
)
如果优化的ZIP文件不存在,则会通过将其重定向到设备 NUL 来抑制错误消息输出。
要了解使用的命令及其工作原理,请打开命令提示符窗口,执行以下命令,并完全阅读为每个命令显示的所有帮助页面。
call /?
del /?
echo /?
for /?
goto /?
if /?
move /?
rd /?
有关2>nul
的详细信息,请参阅Microsoft文章Using command redirection operators。