View previous topic :: View next topic |
Author |
Message |
D1P
Joined: 20 Dec 2004 Posts: 2973 Location: Тбилиси
|
(Separately) Posted: Sun Jul 31, 2011 19:30 Post subject: Рекурсивная распаковка |
|
|
Дано: ветвистое дерево каталогов, вложенность может быть неограниченная. В каталогах файлы, запакованные обычным zip, несколько десятков тысяч всего.
Требуется распаковать все файлы с сохранением структуры каталогов.
Вариант вынести всё через Ctrl+B, распаковать, а потом каким-либо способом восстановить структуру не подходит, потому что такого способа нет.
Как решить задачу? _________________ База знаний о Total Commander
Блог |
|
Back to top |
|
|
Flasher
Joined: 06 Nov 2009 Posts: 14229 Location: Москва
|
(Separately) Posted: Sun Jul 31, 2011 19:42 Post subject: |
|
|
Пока неясно, куда распаковывать - в родительскую для каждого архива директорию или в новую одноимённую директорию, создаваемую внутри родительской?
Также неясно, что значит "с сохранением структуры"? Подразумевается, что при стандартном подходе содержимое всех архивов перекачует в общую папку, а не родительскую для каждого архива?
Мне кажется стоит подождать Tol!k, он скорректирует под сеи нужды этот батник. |
|
Back to top |
|
|
D1P
Joined: 20 Dec 2004 Posts: 2973 Location: Тбилиси
|
(Separately) Posted: Sun Jul 31, 2011 20:08 Post subject: |
|
|
>Пока неясно, куда распаковывать - в текущую для каждого архива директорию или в новую одноимённую директорию, создаваемую внутри текущей?
Проще всего объяснить так: на месте зипованых файлов должны оказаться раззипованные. Никаких новых директорий, никакого перемещения. _________________ База знаний о Total Commander
Блог |
|
Back to top |
|
|
Tol!k
Joined: 01 Apr 2008 Posts: 1727 Location: Арзамас
|
(Separately) Posted: Mon Aug 01, 2011 00:55 Post subject: |
|
|
параметры: "%L" "%%~dpf" -o
важно выделять архивы (поиском или Ctrl+B), а не папку |
|
Back to top |
|
|
D1P
Joined: 20 Dec 2004 Posts: 2973 Location: Тбилиси
|
|
Back to top |
|
|
Flasher
Joined: 06 Nov 2009 Posts: 14229 Location: Москва
|
(Separately) Posted: Mon Aug 01, 2011 17:44 Post subject: |
|
|
Что-то вчера накидал (ин-ета не было - не мог выложить):
Code: | ' Рекурсивная распаковка архивов внутри выделенных каталогов
' Параметры: %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 | См., чтобы путь к 7z.exe соответствовал.
Last edited by Flasher on Tue Aug 02, 2011 12:32; edited 2 times in total |
|
Back to top |
|
|
Tol!k
Joined: 01 Apr 2008 Posts: 1727 Location: Арзамас
|
(Separately) Posted: Mon Aug 01, 2011 18:54 Post subject: |
|
|
D1P wrote: | Tol!k wrote: | параметры: "%L" "%%~dpf" -o |
Спасибо. Это для твоего батника параметры? |
Да, http://forum.wincmd.ru/viewpost.php?p=67240 Только без -o Извини, я похоже, уже спал:
Quote: | -o — каждый архив в отдельную папку с именем архива |
|
|
Back to top |
|
|
D1P
Joined: 20 Dec 2004 Posts: 2973 Location: Тбилиси
|
|
Back to top |
|
|
Flasher
Joined: 06 Nov 2009 Posts: 14229 Location: Москва
|
(Separately) Posted: Mon Aug 01, 2011 21:17 Post subject: |
|
|
D1P
Пож-та. Работа скрипта соответствует ТЗ, или что-то не так? |
|
Back to top |
|
|
Batya
Joined: 15 Dec 2004 Posts: 2221 Location: Москва, Россия
|
(Separately) Posted: Tue Aug 02, 2011 10:01 Post subject: |
|
|
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. _________________ Нет, я не сплю. Я просто медленно моргаю. |
|
Back to top |
|
|
Flasher
Joined: 06 Nov 2009 Posts: 14229 Location: Москва
|
(Separately) Posted: Tue Aug 02, 2011 12:23 Post subject: |
|
|
Batya
1. ОК.
2. Изначально стояло True, просто кое-какие глюки c 7z были, процесс висеть оставался, но там причина, видимо, в другом была. Ещё вчера хотел вернуть, пост пачкать не хотелось. Хоть, конечно, для небольшого числа архивов параллельная распаковка проходит быстрее, не учесть большие списки нельзя, поэтому возвращаю True на место. К тому же сообщение будет появляться своевременно. |
|
Back to top |
|
|
D1P
Joined: 20 Dec 2004 Posts: 2973 Location: Тбилиси
|
|
Back to top |
|
|
Flasher
Joined: 06 Nov 2009 Posts: 14229 Location: Москва
|
(Separately) Posted: Tue Aug 02, 2011 19:34 Post subject: |
|
|
D1P
А зря, сэкономил бы себе время.
2All
На всякий случай сообщаю тем, кому выгодней (например, мне) распаковывать каждый архив в создаваемую папку с базовым именем архива:
замените нижнюю процедуру на эту: Code: | 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 |
|
|
Back to top |
|
|
Volniy
Joined: 15 Dec 2004 Posts: 585 Location: Местный
|
(Separately) Posted: Thu Aug 04, 2011 04:05 Post subject: |
|
|
Batya wrote: |
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" |
...или использовать специально заточенную для сравнения строк функцию StrComp: Code: | If StrComp(FSO.GetExtensionName(FilePath), WScript.Arguments(1) ,1) = 0 Then |
|
|
Back to top |
|
|
Flasher
Joined: 06 Nov 2009 Posts: 14229 Location: Москва
|
(Separately) Posted: Sat Aug 13, 2011 23:56 Post subject: |
|
|
Подумал, пусть тут тоже будет:
Code: | '•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
' Распаковка выделенных архивов и архивов в структуре
' выделенных каталогов в одноименные папки рядом с архивами
' Параметры: %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 | Распаковываться будут архивы только с поддерживаемыми форматами (42 расширения). |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|