Я предлагаю следующий комментировали пакетный файл для выполнения этой задачи:
@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
в последних два ДЛЯ петель перенаправляет вывод сообщения об ошибке с помощью команды DIR для обработки STDERR в случае отсутствия каталога или файла не найдено в устройство NUL, чтобы подавить его. Оператор перенаправления >
должен быть экранирован здесь с символом caret ^
, который должен интерпретироваться как оператор перенаправления при выполнении команды DIR и еще не разобрать для командной строки.
WinRAR поддерживает множество типов архива при извлечении. Но WinRAR.exe
является графическим приложением и поэтому не поддерживает перечисление содержимого архивного файла на консоль, так как поддерживает Rar.exe
.
Консоль версия Rar.exe
, а также поддержка свободной консольного приложения UnRAR.exe
и список содержимого архива файлов для обработки STDOUT в различных форматах.
Эта разница на поддерживаемых команд между WinRAR.exe
и Rar.exe
/UnRAR.exe
можно увидеть, открыв в WinRAR помощь, нажав в меню Справка по пункту меню разделы справки, открытие на вкладке справки Содержание элемент списка Режим командной строки, открывая элемент списка Команды, нажав на элемент списка Алфавитный список команд и сравнив этот список с командами, перечисленными и описанными в текстовом файле Rar.txt
в папке с файлами программ WinRAR, который является руководством для консольной версии.
Rar.txt
перечислены и описаны:
л [т [а], Ь] ... Содержание Список архив [технические [все], голые]
v [т [а], Ь]. .. Подробный список содержимого архива [технический [все], голый].
Помощь в WinRAR действительно содержит ли команду L, ни команда v.
Было бы, конечно, также можно запустить Rar.exe
или UnRAR.exe
на каждом * .rar файл с помощью команды lb
, подсчитать количество выходных линий, как это сделано в выше пакетный файл для подсчета файлов и извлечь * .rar архив в зависимости от количества строк в текущем каталоге (только 1 строка) или в подкаталоге.
Но следует учитывать, что при использовании формата голого списка и только 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 Using command redirection operators.
Я знаю, Winzip имеет возможность перечислить то, что находится внутри архива, не извлекая его. Я бы предположил, что 7zip и Winrar тоже. Вы посмотрели документацию для них. – Squashman