我建议为此任务使用以下注释批处理文件:
@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输出的错误消息重定向到处理STDERR,以防没有目录或找不到文件到设备NUL以抑制它。重定向运算符>
必须在此处使用字符插入符号进行转义,^
以便在执行DIR命令行时解释为重定向运算符,而不是在解析FOR命令行时。
WinRAR在解压时支持多种存档类型。但WinRAR.exe
它是一个 GUI 应用程序,因此不支持将存档文件的内容列出到控制台作为Rar.exe
支持。
控制台版本Rar.exe
和免费控制台应用程序UnRAR.exe
都支持列出存档文件内容以处理各种格式的STDOUT。
WinRAR.exe
和Rar.exe
/之间支持的命令的差异UnRAR.exe
可以通过在 WinRAR 中打开帮助来查看,方法是在菜单项帮助主题上单击菜单帮助,在帮助选项卡上打开内容列表项命令行模式,打开列表项命令,单击列表项按字母顺序排列的命令列表 ,并将此列表与WinRAR的程序文件文件夹中的文本文件中列出和描述的命令进行比较,该文件是控制台版本的手册。Rar.txt
Rar.txt
列出并描述:
l[t[a],b] ... 列出存档内容 [技术 [全部],裸露]
v[t[a],b] ... 详细列出存档内容 [技术 [全部],裸露]。
WinRAR的帮助是否包含命令l或命令v。
当然也可以使用命令在每个 *.rar 文件上运行Rar.exe
或运行,计算上面批处理文件中输出的行数以计算文件并根据行数提取 *.rar 存档文件到当前目录(仅 1 行)或子目录。UnRAR.exe
lb
但应该考虑到,在使用裸列表格式并且只有 1 行输出时,该行可以是存档文件的名称或存档的空文件夹的名称。解决方案将使用标准列表命令并更多地分析属性,因为目录具有属性D
而文件没有此属性。
对于 *.7z 和 *.zip 文件,必须使用7z.exe
或进行编码7za.exe
。7-Zip的帮助还描述了可用的命令和开关,如WinRAR的帮助。
但是与发布的解决方案相比,所有这些努力都没有多大意义,因为必须完全提取存档文件并且移动文件非常快,因为文件分配表中的条目被修改并且没有数据被复制或移动全部。
首先单独运行7-Zip或Rar仅列出每个存档文件内容,分析列表,然后在存档文件上再次运行7-Zip或Rar以进行提取比仅运行WinRAR 3 次(或更少)以提取所有文件要慢得多存档,然后移动一些文件并删除一些目录。
要了解使用的命令及其工作原理,请打开命令提示符窗口,在其中执行以下命令,并仔细阅读每个命令显示的所有帮助页面。
call /?
dir /?
echo /?
endlocal /?
for /?
goto /?
move /?
rd /?
set /?
setlocal /?
另请参阅 Microsoft TechNet 文章使用命令重定向运算符。