我正在尝试创建一个批处理脚本,该脚本将压缩每个子目录中除最新(或最新的几个)之外的所有内容。我目前正在 Windows 中尝试使用 7-Zip,但从技术上讲,该目录位于 Linux 服务器上,因此欢迎任何针对 Linux 命令的建议。
目录结构是这样的:
Directory-Parent
---Sub-Directory-1
--------File1
--------File2
--------File3
---Sub-Directory-2
--------File1
--------File2
我想在Directory-Parent
级别运行一个批处理,该批处理将在除最新文件(或少数文件,如果可能)之外的所有文件的每个子目录中创建一个zip。我还想将年份添加到 zip 文件名的末尾。
所以结果是:
Directory-Parent
-Sub-Directory-1
--------File1
--------Sub-Directory-12019.zip
---Sub-Directory-2
--------File1
--------Sub-Directory-22019.zip
我尝试了嵌套的 for
循环,但似乎无法得到它。我已在集合 (IN) 中尝试使用带有skip和dir
的for
命令,但无法让它工作。
我目前有以下脚本。
SET theYear=2019
For /D %%d in (*.*) do 7z a "%%d\%%d%theYear%.zip" ".\%%d\*"
这一切都完成了,只是我不知道如何排除每个文件夹中的最新文件(根据上次修改时间的最新文件)。
最佳答案
此批处理文件可用于此任务:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "FilesToIgnore=1"
set "theYear=%DATE:~-4%"
set "ListFile=%Temp%\%~n0.lst"
del "%ListFile%" 2>nul
for /D %%I in (*) do call :CompressFiles "%%I"
goto EndBatch
:CompressFiles
pushd %1
set "ZipFile=%~nx1%theYear%.zip"
for /F "skip=%FilesToIgnore% eol=| delims=" %%J in ('dir /A-D /B /O-D /TW 2^>nul ^| %SystemRoot%\System32\findstr.exe /I /L /V /X /C:"%ZipFile%"') do >>"%ListFile%" echo %%J
if exist "%ListFile%" (
echo Compressing files in directory %1 ...
7z.exe a -bd -bso0 -i"@%ListFile%" -mx9 -scsDOS -- "%ZipFile%"
del "%ListFile%"
)
popd
goto :EOF
:EndBatch
endlocal
批处理文件根据动态环境变量 DATE
的区域相关日期字符串动态设置环境变量 theYear
。请在命令提示符窗口中执行 echo %DATE:~-4%
并验证输出是否为当前年份,因为 echo %DATE%
输出当前本地日期的最后四位字符为年份。
批处理文件会忽略每个目录中的FilesToIgnore
最新文件。如果 ZIP 文件在上次执行批处理文件时已存在,则也会被忽略。 ZIP 文件永远不会包含在 FilesToIgnore
的数量中,因为它已经被 findstr
过滤掉了,该命令过滤了命令 dir
的输出,该命令输出文件名,而没有当前目录中的路径按上次修改时间排序,最新的文件最先输出,最旧的文件最后输出。
使用的开关和参数请阅读7-Zip的帮助。
为了了解所使用的命令及其工作原理,请打开命令提示符窗口,执行以下命令,并仔细阅读每个命令显示的所有帮助页面。
删除/?
目录/?
回显/?
endlocal/?
findstr/?
对于/?
转到/?
如果/?
popd/?
pushd/?
设置/?
setlocal/?
阅读有关 Using Command Redirection Operators 的 Microsoft 文章了解 2>nul
和 |
的解释。重定向运算符 >
和 |
必须在 FOR 命令行上使用脱字符号 ^
进行转义才能解释为文字Windows 命令解释器在执行命令 FOR 之前处理此命令行时的字符,该命令使用在后台启动的单独命令进程来执行嵌入式命令行。
更新: 7-Zip 版本 19.00.0.0 会输出警告,并在使用命令行时在每个子目录中创建一个空 ZIP 文件,如下所示,最初使用于批处理文件。我首先认为这是 7-Zip 版本 19.00.0.0 的错误,因为根据其帮助和 7-Zip<,该版本还应该支持 --
/em> 版本 16.04.0.0 可使用命令行:
7z.exe a -bd -bso0 -mx9 -scsDOS -- "%ZipFile%" "@%ListFile%"
必须从此命令行中删除 --
才能使其与 7-Zip 版本 19.00.0.0 一起使用。
所以我reported this issue 7-Zip 的作者很快回复解释了为什么使用 --
会导致搜索文件名以 @
开头的文件,因为 7-Zip 版本 19.00.0.0:
We need some way to add
@file
and-file
names from command line.
So--
stops@
and-
parsing, and 7-Zip searches exact names.
It's more safe to use-i@listfile
instead.
因此我更新了批处理文件代码并使用选项 -i
指定列表文件,这是指定列表文件的最安全方法。
关于batch-file - 如何将文件夹的每个子文件夹中除最新文件之外的所有文件压缩为每个子文件夹一个 ZIP 文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57613888/