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

时间:2017-02-03 21:57:21

标签: batch-file zip unzip rar unrar

为了节省空间和组织,我正在我的本地和网络文件夹中压缩一堆文件。它们主要是CAD文件,如stp,igs等。

已经存在zip文件,有些是由其他用户提取的,但zip文件仍然存在于文件夹中,这会占用空间。

是否有命令行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.这些主要用于归档。

任何帮助或想法都将不胜感激。

2 个答案:

答案 0 :(得分:3)

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

@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 执行的操作 批处理文件包含的注释行比实际命令行多得多。

最后两个 FOR 循环中的

2>nul重定向错误消息输出命令 DIR 以处理 STDERR 以防否目录或没有找到设备 NUL 的文件来抑制它。必须使用字符插入符>对重定向操作符^进行转义,以便在执行 DIR 命令行时解释为重定向操作符,而不是在解析 FOR <时/ strong>命令行。

WinRAR 在提取时支持许多归档类型。但WinRAR.exe是一个GUI应用程序,因此不支持将归档文件的内容列为Rar.exe支持的控制台。

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

通过在菜单项上单击菜单帮助,在WinRAR中打开帮助,可以看到WinRAR.exeRar.exe / UnRAR.exe之间支持的命令的差异帮助主题,在帮助标签上打开内容列表项命令行模式,打开列表项命令,点击在列表项字母命令列表上,并将此列表与 WinRAR 的程序文件文件夹中文本文件Rar.txt中列出和描述的命令进行比较,该文件夹是控制台版本。

Rar.txt列出并描述:

  

l [t [a],b] ...列出档案内容[技术[全部],裸]
  v [t [a],b] ...详细列出档案内容[技术[全部],裸]。

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

当然也可以使用命令Rar.exe在每个* .rar文件上运行UnRAR.exelb,将上面批处理文件中输出的行数计算到计算文件并提取* .rar存档文件,具体取决于当前目录的行数(仅限1行)或子目录。

但是应该考虑到,在使用裸列表格式并且只有1行输出时,该行可以是存档文件的名称或存档的空文件夹的名称。解决方案是使用标准列表命令并更多地分析属性,因为目录具有属性D而文件没有此属性。

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

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

分别运行 7-Zip Rar ,首先列出每个存档文件内容,分析列表,然后运行 7 -zip Rar 再次在归档文件上进行提取比运行 WinRAR 只需要3次(或更少)来提取所有归档然后移动一些文件并删除一些目录。

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

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

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

答案 1 :(得分:2)

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

@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\_StackOverflow\Noodles\Filter0.8.zip contains 4 files
Archive q:\Test\2016\12\16\Path.rar contains 7 files
Archive q:\Test\_AllHelp.Win\allhelp.zip contains 7 files
Archive q:\Test\2017-02\pkzipc_40.rar contains 10 files