Total Commander Forum Index Total Commander
Форум поддержки пользователей Total Commander
Сайты: Все о Total Commander | Totalcmd.net | Ghisler.com | RU.TCKB
 
 RulesRules   SearchSearch   FAQFAQ   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Рекурсивная распаковка
Goto page 1, 2, 3 ... 27, 28, 29  Next
 
Post new topic   Reply to topic    Total Commander Forum Index -> Автоматизация Total Commander printer-friendly view
View previous topic :: View next topic  
Author Message
D1P



Joined: 20 Dec 2004
Posts: 2855
Location: Москва

Post (Separately) Posted: Sun Jul 31, 2011 19:30    Post subject: Рекурсивная распаковка Reply with quote

Дано: ветвистое дерево каталогов, вложенность может быть неограниченная. В каталогах файлы, запакованные обычным zip, несколько десятков тысяч всего.
Требуется распаковать все файлы с сохранением структуры каталогов.

Вариант вынести всё через Ctrl+B, распаковать, а потом каким-либо способом восстановить структуру не подходит, потому что такого способа нет.

Как решить задачу?
_________________
База знаний о Total Commander
Блог
Back to top
View user's profile Send private message
Flasher



Joined: 06 Nov 2009
Posts: 11878
Location: Москва

Post (Separately) Posted: Sun Jul 31, 2011 19:42    Post subject: Reply with quote

Пока неясно, куда распаковывать - в родительскую для каждого архива директорию или в новую одноимённую директорию, создаваемую внутри родительской?
Также неясно, что значит "с сохранением структуры"? Подразумевается, что при стандартном подходе содержимое всех архивов перекачует в общую папку, а не родительскую для каждого архива?

Мне кажется стоит подождать Tol!k, он скорректирует под сеи нужды этот батник.
Back to top
View user's profile Send private message
D1P



Joined: 20 Dec 2004
Posts: 2855
Location: Москва

Post (Separately) Posted: Sun Jul 31, 2011 20:08    Post subject: Reply with quote

>Пока неясно, куда распаковывать - в текущую для каждого архива директорию или в новую одноимённую директорию, создаваемую внутри текущей?

Проще всего объяснить так: на месте зипованых файлов должны оказаться раззипованные. Никаких новых директорий, никакого перемещения.
_________________
База знаний о Total Commander
Блог
Back to top
View user's profile Send private message
Tol!k



Joined: 01 Apr 2008
Posts: 1724
Location: Арзамас

Post (Separately) Posted: Mon Aug 01, 2011 00:55    Post subject: Reply with quote

параметры: "%L" "%%~dpf" -o
Exclamation важно выделять архивы (поиском или Ctrl+B), а не папку
Back to top
View user's profile Send private message
D1P



Joined: 20 Dec 2004
Posts: 2855
Location: Москва

Post (Separately) Posted: Mon Aug 01, 2011 08:18    Post subject: Reply with quote

Tol!k wrote:
параметры: "%L" "%%~dpf" -o

Спасибо. Это для твоего батника параметры?
_________________
База знаний о Total Commander
Блог
Back to top
View user's profile Send private message
Flasher



Joined: 06 Nov 2009
Posts: 11878
Location: Москва

Post (Separately) Posted: Mon Aug 01, 2011 17:44    Post subject: Reply with quote

Что-то вчера накидал (ин-ета не было - не мог выложить):
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
View user's profile Send private message
Tol!k



Joined: 01 Apr 2008
Posts: 1724
Location: Арзамас

Post (Separately) Posted: Mon Aug 01, 2011 18:54    Post subject: Reply with quote

D1P wrote:
Tol!k wrote:
параметры: "%L" "%%~dpf" -o

Спасибо. Это для твоего батника параметры?

Да, http://forum.wincmd.ru/viewpost.php?p=67240 Только без -o Извини, я похоже, уже спал:
Quote:
-o — каждый архив в отдельную папку с именем архива
Back to top
View user's profile Send private message
D1P



Joined: 20 Dec 2004
Posts: 2855
Location: Москва

Post (Separately) Posted: Mon Aug 01, 2011 21:15    Post subject: Reply with quote

Tol!k
Спасибо, отличнейшим образом всё сработало.
Flasher
Тебе тоже спасибо.
_________________
База знаний о Total Commander
Блог
Back to top
View user's profile Send private message
Flasher



Joined: 06 Nov 2009
Posts: 11878
Location: Москва

Post (Separately) Posted: Mon Aug 01, 2011 21:17    Post subject: Reply with quote

D1P
Пож-та. Работа скрипта соответствует ТЗ, или что-то не так?
Back to top
View user's profile Send private message
Batya



Joined: 15 Dec 2004
Posts: 2198
Location: Москва, Россия

Post (Separately) Posted: Tue Aug 02, 2011 10:01    Post subject: Reply with quote

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
View user's profile Send private message
Flasher



Joined: 06 Nov 2009
Posts: 11878
Location: Москва

Post (Separately) Posted: Tue Aug 02, 2011 12:23    Post subject: Reply with quote

Batya
1. ОК.
2. Изначально стояло True, просто кое-какие глюки c 7z были, процесс висеть оставался, но там причина, видимо, в другом была. Ещё вчера хотел вернуть, пост пачкать не хотелось. Rolling Eyes Хоть, конечно, для небольшого числа архивов параллельная распаковка проходит быстрее, не учесть большие списки нельзя, поэтому возвращаю True на место. К тому же сообщение будет появляться своевременно.
Back to top
View user's profile Send private message
D1P



Joined: 20 Dec 2004
Posts: 2855
Location: Москва

Post (Separately) Posted: Tue Aug 02, 2011 19:11    Post subject: Reply with quote

Flasher
До твоего скрипта руки не дошли, всё сделал батником.
_________________
База знаний о Total Commander
Блог
Back to top
View user's profile Send private message
Flasher



Joined: 06 Nov 2009
Posts: 11878
Location: Москва

Post (Separately) Posted: Tue Aug 02, 2011 19:34    Post subject: Reply with quote

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
View user's profile Send private message
Volniy



Joined: 15 Dec 2004
Posts: 585
Location: Местный

Post (Separately) Posted: Thu Aug 04, 2011 04:05    Post subject: Reply with quote

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
View user's profile Send private message
Flasher



Joined: 06 Nov 2009
Posts: 11878
Location: Москва

Post (Separately) Posted: Sat Aug 13, 2011 23:56    Post subject: Reply with quote

Подумал, пусть тут тоже будет:
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
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Total Commander Forum Index -> Автоматизация Total Commander All times are GMT + 4 Hours
Goto page 1, 2, 3 ... 27, 28, 29  Next
Page 1 of 29

 
Jump to:  
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