如何检查 zip 或 rar 文件是否包含 1 个或多个文件?

How to check if zip or rar file contains 1 or more files?

出于保存 space 和整理的目的,我将一堆文件压缩到我的本地和网络文件夹中。主要是CAD文件,如stp、igs等

已经存在 zip 文件,一些已被其他用户提取,但 zip 文件仍然存在于文件夹中,这占用了 space。

有没有命令行zip、rar、7z。等以查明存档文件是否仅包含 1 个文件?

我想解决这个问题,因为我会将包含单个文件的档案提取到当前目录,同时将包含 1 个以上文件的档案提取到 \archivename\ 文件夹。否则,一个包含 30 个 STP 文件的文件夹会突然在其中提取 30 个文件夹和 30 个我不想要的文件。

我目前使用 WinRAR 的批处理文件进行解压,使用另一个程序检查重复项,然后 WinRAR 进行批处理重新压缩它们基于文件扩展名。 (原因:人们使用不同的归档方法,到处都是重复的文件。)

示例批处理文件:

for /F "delims=," %%f in ('dir *.stp /B' ) do (%path% a -afzip -r- -m5 -ed -ep -or -tl -y -df "%%f".zip "%%f")

for /F "delims=;" %%f in ('dir *.7z /B /S' ) do (%path% x -OR -ilogC:\Users\XXXX\Desktop\myLog.txt "%%f" "%%~dpf"\"%%~nf"\)

一旦我可以检查 zip 中的文件数,我将添加一个递归函数。

我可以用NTFS压缩,但我也想整理文件夹,有些文件夹里有1000个文件,我肯定想把它压缩到1个。这些主要是为了存档。

如有任何帮助或想法,我们将不胜感激。

我建议为此任务使用以下注释批处理文件:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem Extract all 7-Zip, RAR and ZIP archives in current directory into
rem subdirectories with name of archive file as name for subdirectory (-ad)
rem with running WinRAR for extraction in background (-ibck) which means
rem minimized to system tray with restoring also last access time (-tsa)
rem and creation time (-tsc) if existing in archive file and with skipping
rem files on extraction perhaps already present in the subdirectory with
rem same last modification time (-u), but overwriting automatically older
rem files in subdirectory if archive file contains an existing file with
rem a newer last modification time (-y) ignoring all errors (also -y).

for %%I in (7z rar zip) do "%ProgramFiles%\WinRAR\WinRAR.exe" x -ad -ibck -tsa -tsc -u -y *.%%I

rem If a subdirectory contains only 1 file, move that file to the current
rem directory with overwriting a perhaps already existing file with same
rem name in current directory and then remove the subdirectory.

for /D %%I in (*) do call :CheckSubDir "%%I"

rem Exit processing of the batch file without fall through to subroutine.
endlocal
goto :EOF

rem The subroutine CheckSubDir first checks for directories in directory
rem passed as parameter to the subroutine. A directory containing at
rem least one subdirectory is kept without any further processing.

rem If the directory does not contain a subdirectory, it searches for files
rem in the directory. If there are at least 2 files, the directory is kept
rem without any further processing.

rem But if the directory contains only 1 file, this file is moved to
rem current directory. Then the empty directory is deleted before exiting
rem the subroutine and continue batch file processing in calling loop.
rem Each directory containing no subdirectory and no file is removed, too.

:CheckSubDir
for /F "delims=" %%D in ('dir /AD /B "%~1\*" 2^>nul') do goto :EOF
setlocal EnableDelayedExpansion
set FileCount=0
for /F "delims=" %%F in ('dir /A-D /B "%~1\*" 2^>nul') do (
    set /A FileCount+=1
    if !FileCount! == 2 endlocal & goto :EOF
    set "FileName=%%F"
)
if %FileCount% == 1 move /Y "%~1\%FileName%" "%FileName%"
rd "%~1"
endlocal
goto :EOF

请阅读评论以了解此批处理文件在使用 WinRAR.
时执行的详细信息 批处理文件包含的注释行比实际命令行多得多。

2>nul在最后两个FOR循环中将命令DIR输出的错误信息重定向到handle STDERR 如果没有找到目录或文件到设备 NUL 来抑制它。重定向运算符 > 必须在此处使用字符插入符 ^ 进行转义,以便在执行 DIR 命令行时被解释为重定向运算符,而不是在解析 FOR命令行。

WinRAR 支持多种压缩文件类型。但是 WinRAR.exe 是一个 GUI 应用程序,因此不支持将存档文件的内容列到控制台,因为 Rar.exe 支持。

控制台版本 Rar.exe 以及免费控制台应用程序 UnRAR.exe 都支持列出存档文件内容以处理各种格式的 STDOUT

WinRAR.exeRar.exe/UnRAR.exe 之间在支持命令上的差异可以通过在 WinRAR 中单击菜单 帮助[=111 打开帮助来查看=] 在菜单项 帮助主题 上打开帮助选项卡 内容 列表项 命令行模式 ,打开列表项 Commands,单击列表项 Alphabetic commands list 并将此列表与文本文件 [=21= 中列出和描述的命令进行比较] 在 WinRAR 的程序文件文件夹中,这是控制台版本的手册。

Rar.txt 列出并描述:

l[t[a],b] ... List archive contents [technical [all], bare]
v[t[a],b] ... Verbosely list archive contents [technical [all], bare].

WinRAR的帮助是否包含命令l或命令v.

当然也可以运行 Rar.exeUnRAR.exe 在每个*.rar 文件上使用命令lb,计算输出的行数为在上面的批处理文件中完成计算文件并根据行数将 *.rar 存档文件提取到当前目录(仅 1 行)或子目录。

但需要注意的是,在使用裸列表格式且仅输出1行时,此行可以是归档文件的名称或归档的空文件夹的名称。解决方案将使用标准列表命令并更多地分析属性,因为目录具有属性 D 而文件没有此属性。

对于 *.7z 和 *.zip 文件,必须使用 7z.exe7za.exe 对其进行编码。 7-Zip 的帮助也描述了可用的命令和开关,如 WinRAR.

的帮助

但是与已发布的解决方案相比,所有这些努力都没有多大意义,因为必须提取存档文件并且移动文件非常快,因为文件分配 table 中的条目是已修改,根本没有复制或移动任何数据。

运行 7-ZipRar 单独列出 each 存档文件内容,分析列表,运行ning 7-ZipRar 再次对存档文件进行提取是多比 运行ning WinRAR 慢 3 次(或更少)提取所有档案,然后移动一些文件并删除一些目录。

要了解使用的命令及其工作原理,请打开命令提示符 window,在其中执行以下命令,并仔细阅读为每个命令显示的所有帮助页面。

  • call /?
  • dir /?
  • echo /?
  • endlocal /?
  • for /?
  • goto /?
  • move /?
  • rd /?
  • set /?
  • setlocal /?

另请参阅 Microsoft TechNet 文章 Using command redirection operators

从字面上看问题,以下批处理使用 7z.exe(必须通过路径访问)列表 (l)-选项通过过滤最后一行来获取存档中包含的文件数。

@Echo off
Set Base=q:\Test
Pushd "%Base%"
For /f "delims=" %%A in (
  'Dir /B/S/A-D *.zip *.7z *.rar'
) Do For /f "tokens=5" %%B in (
  ' 7z.exe l "%%~A" ^| findstr "files$" '
) Do If %%B equ 1 (
  Echo Archive %%A contains 1 file
) else (
  Echo Archive %%A contains %%B files
)
Popd

示例输出:

Archive q:\Test\archiv.7z contains 135 files
Archive q:\Test\PoSh\powershellitunes\PowerScript-itunes.7z contains 1 file
Archive q:\Test\PoSh\_pdf_itextsharp\extract_pdf_pages_into_new_323689.zip contains 3 files
Archive q:\Test\_Whosebug\Noodles\Filter0.8.zip contains 4 files
Archive q:\Test16\Path.rar contains 7 files
Archive q:\Test\_AllHelp.Win\allhelp.zip contains 7 files
Archive q:\Test17-02\pkzipc_40.rar contains 10 files