Рекурсивная распаковка
Модераторы: d-view, Моторокер, Avada, CaptainFlint, Nik
Рекурсивная распаковка
Дано: ветвистое дерево каталогов, вложенность может быть неограниченная. В каталогах файлы, запакованные обычным zip, несколько десятков тысяч всего.
Требуется распаковать все файлы с сохранением структуры каталогов.
Вариант вынести всё через Ctrl+B, распаковать, а потом каким-либо способом восстановить структуру не подходит, потому что такого способа нет.
Как решить задачу?
Требуется распаковать все файлы с сохранением структуры каталогов.
Вариант вынести всё через Ctrl+B, распаковать, а потом каким-либо способом восстановить структуру не подходит, потому что такого способа нет.
Как решить задачу?
Пока неясно, куда распаковывать - в родительскую для каждого архива директорию или в новую одноимённую директорию, создаваемую внутри родительской?
Также неясно, что значит "с сохранением структуры"? Подразумевается, что при стандартном подходе содержимое всех архивов перекачует в общую папку, а не родительскую для каждого архива?
Мне кажется стоит подождать Tol!k, он скорректирует под сеи нужды этот батник.
Также неясно, что значит "с сохранением структуры"? Подразумевается, что при стандартном подходе содержимое всех архивов перекачует в общую папку, а не родительскую для каждого архива?
Мне кажется стоит подождать Tol!k, он скорректирует под сеи нужды этот батник.
Что-то вчера накидал (ин-ета не было - не мог выложить):
См., чтобы путь к 7z.exe соответствовал.
Код: Выделить всё
' Рекурсивная распаковка архивов внутри выделенных каталогов
' Параметры: %L <расширение архива>
'==========================================
Dim FSO, WSH
Set FSO = CreateObject("Scripting.FileSystemObject")
Set WSH = CreateObject("WScript.Shell")
Proga = WSH.ExpandEnvironmentStrings("%COMMANDER_PATH%\Utils\7-Zip\7z.exe")
With FSO.OpenTextFile(WScript.Arguments(0), 1)
Do While Not .AtEndOfStream
F = Trim(.ReadLine)
If F <> "" Then
If FSO.FolderExists(F) Then ForFolder FSO.GetFolder(F)
End If
Loop
.Close
End With
WSH.Popup "Распаковка завершена!", 1.4, "Результат", 64
Set FSO = Nothing
Set WSH = Nothing
WScript.Quit
Sub ForFolder(Folder)
Dim N
For Each N In Folder.Files
ForFile N
Next
For Each N In Folder.SubFolders
ForFolder N
Next
End Sub
Sub ForFile(File)
If LCase(FSO.GetExtensionName(File)) = LCase(WScript.Arguments(1)) Then WSH.Run """" & Proga & """x """ & File & """ -o""" & File.ParentFolder & "\"" -y", 0, True
End Sub
Последний раз редактировалось Flasher Вт авг 02, 2011 12:32, всего редактировалось 2 раза.
Да, http://forum.wincmd.ru/viewpost.php?p=67240 Только без -o Извини, я похоже, уже спал:D1P писал(а):Спасибо. Это для твоего батника параметры?Tol!k писал(а):параметры: "%L" "%%~dpf" -o
-o — каждый архив в отдельную папку с именем архива
Flasher
Пару советов:
1. При сравнении расширений "FSO.GetExtensionName(FilePath) = WScript.Arguments(1)" лучше приводить к одному регистру "UCase(FSO.GetExtensionName(FilePath)) = UCase(WScript.Arguments(1))" или использовать InStr "InStr(1, FSO.GetExtensionName(FilePath), WScript.Arguments(1), 1) > 0".
2. Думаю, что для поставленной задачи, т.к. арховов "несколько десятков тысяч", лучше использовать не параллельную распаковку, а последовательную. При вызове WSH.Run укажи третий параметр со значением True.
Пару советов:
1. При сравнении расширений "FSO.GetExtensionName(FilePath) = WScript.Arguments(1)" лучше приводить к одному регистру "UCase(FSO.GetExtensionName(FilePath)) = UCase(WScript.Arguments(1))" или использовать InStr "InStr(1, FSO.GetExtensionName(FilePath), WScript.Arguments(1), 1) > 0".
2. Думаю, что для поставленной задачи, т.к. арховов "несколько десятков тысяч", лучше использовать не параллельную распаковку, а последовательную. При вызове WSH.Run укажи третий параметр со значением True.
Нет, я не сплю. Я просто медленно моргаю.
Batya
1. ОК.
2. Изначально стояло True, просто кое-какие глюки c 7z были, процесс висеть оставался, но там причина, видимо, в другом была. Ещё вчера хотел вернуть, пост пачкать не хотелось.
Хоть, конечно, для небольшого числа архивов параллельная распаковка проходит быстрее, не учесть большие списки нельзя, поэтому возвращаю True на место. К тому же сообщение будет появляться своевременно.
1. ОК.
2. Изначально стояло True, просто кое-какие глюки c 7z были, процесс висеть оставался, но там причина, видимо, в другом была. Ещё вчера хотел вернуть, пост пачкать не хотелось.
D1P
А зря, сэкономил бы себе время.
2All
На всякий случай сообщаю тем, кому выгодней (например, мне) распаковывать каждый архив в создаваемую папку с базовым именем архива:
замените нижнюю процедуру на эту:
А зря, сэкономил бы себе время.
2All
На всякий случай сообщаю тем, кому выгодней (например, мне) распаковывать каждый архив в создаваемую папку с базовым именем архива:
замените нижнюю процедуру на эту:
Код: Выделить всё
Sub ForFile(File)
If LCase(FSO.GetExtensionName(File)) = LCase(WScript.Arguments(1)) Then
On Error Resume Next
NF = FSO.CreateFolder(File.ParentFolder & "\" & FSO.GetBaseName(File) & "\")
WSH.Run """" & Proga & """ x """ & File & """ -o""" & NF & """ -y", 0, True
End If
End Sub...или использовать специально заточенную для сравнения строк функцию StrComp:Batya писал(а): 1. При сравнении расширений "FSO.GetExtensionName(FilePath) = WScript.Arguments(1)" лучше приводить к одному регистру "UCase(FSO.GetExtensionName(FilePath)) = UCase(WScript.Arguments(1))" или использовать InStr "InStr(1, FSO.GetExtensionName(FilePath), WScript.Arguments(1), 1) > 0"
Код: Выделить всё
If StrComp(FSO.GetExtensionName(FilePath), WScript.Arguments(1) ,1) = 0 ThenПодумал, пусть тут тоже будет:
Распаковываться будут архивы только с поддерживаемыми форматами (42 расширения).
Код: Выделить всё
'•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
' Распаковка выделенных архивов и архивов в структуре
' выделенных каталогов в одноименные папки рядом с архивами
' Параметры: %L <расширения архивов через запятую>
' Пример: %L 7z,7zip,arc,bzip2,rar,zip
' Автор - Flasher ©
'•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
Dim WSH, FSO
Set WSH = CreateObject("WScript.Shell")
Set FSO = CreateObject("Scripting.FileSystemObject")
Proga = WSH.ExpandEnvironmentStrings("%COMMANDER_PATH%\Utils\7-Zip\7z.exe")
With WScript.Arguments
On Error Resume Next
List = .Item(0)
Filt = .Item(1)
If Len(List) > 0 And .Count < 2 Then
MsgBox "Укажите оба параметра!",_
vbExclamation, " Рекурсивная упаковка"
Wscript.Quit
End If
End With
If Err.Number > 0 Then
MsgBox "Не выбраны элементы для распаковки!", vbExclamation,_
" Рекурсивная пофайловая распаковка"
End If
Set Dict = CreateObject("Scripting.Dictionary")
Exts = "7z, 7zip, arj, bz2, bzip2, cab, chm, chw, cpio, cramfs, deb, dmg, doc, exe, fat, gz, gzip, hfs, hxs, iso, lha, lzma, mbr, msi, ntfs, ppt, rar, rpm, scap, squashfs, swm, tar, taz, tbz, tbz2, tgz, vhd, wim, xar, xls, xz, zip"
For Each E in Split(Exts, ", ")
Dict.Add Trim(E), ""
Next
With FSO.OpenTextFile(List, 1)
Do While Not .AtEndOfStream
F = Trim(.ReadLine)
If F <> "" Then
If FSO.FolderExists(F) Then
ForFolder FSO.GetFolder(F)
Else ForFile F
End If
End If
Loop
.Close
End With
Set Dict = Nothing
WSH.Popup "Распаковка завершена!", 1.4 , "Результат", 64
Set WSH = Nothing
Set FSO = Nothing
WScript.Quit
Sub ForFolder(Folder)
Dim N
For Each N In Folder.SubFolders
ForFolder N
Next
For Each N In Folder.Files
ForFile N
Next
End Sub
Sub ForFile(File)
For Each Fi in Split(Filt,",")
If StrComp(Fi,FSO.GetExtensionName(File),1) = 0 And Dict.Exists(LCase(Fi)) Then
NF = FSO.CreateFolder(FSO.GetParentFolderName(File) & "\" & FSO.GetBaseName(File) & "\" )
WSH.Run """" & Proga & """ x """ & File & """ -o""" & NF & """ -y", 0, True
End If
Next
End Sub