Модераторы: ginnie, korob2001

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как разархивировать ZIP архив? 
:(
    Опции темы
korob2001
Дата 4.11.2004, 18:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2871
Регистрация: 29.12.2002

Репутация: 6
Всего: 61



Привет!

Вобщем проблема такая: Есть каталог, в котором примерно 4000 ZIP архивов.
Необходимо открыть этот каталог и пройти по каждому архиву, с этим проблем нет. На каждой итерации цикла, открывать текущий архив и разархивировать его в другой каталог. При этом, файл который содержится в zip'e, должен сохранить своё имя. В каждом архиве, по одному файлу.
Вобщем нужно что бы во втором каталоге получилось около 4000 файлов из zip архивов.

Пробовал читать доки по модулю Archive::Zip, но ничего не понял, правда понял как запихнуть файл в .zip, а вот с обратным процессом проблема. smile
Может кто сталкивался с такой траблой?

Заранее спасибо.
Денис


--------------------
"Время проходит", - привыкли говорить вы по неверному пониманию. 
"Время стоит - проходите вы".
PM MAIL WWW ICQ MSN   Вверх
chaos
Дата 5.11.2004, 08:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Серийный программист
****


Профиль
Группа: Завсегдатай
Сообщений: 2979
Регистрация: 7.7.2004
Где: Екатеринбург

Репутация: 3
Всего: 44



самый простой способ
Код

system("unzip blablabla");

smile
PM WWW   Вверх
GoodBoy
Дата 5.11.2004, 11:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Главный джедай
****


Профиль
Группа: Модератор
Сообщений: 3886
Регистрация: 8.1.2003
Где: КМВ

Репутация: нет
Всего: 83



кстати, можно ещё выполнить вот такой вызов:
Код
`tar xvfz archive.tar.gz -C /path/to/unzipped/files`;

где вот это: -C /path/to/unzipped/files указывается для того, чтобы раскрыть аржив в директорию, отличную от той, где он лежит...


--------------------
Чем дальше в лес, тем толще партизаны...

Цитата(igorold @  1.5.2016,  17:40 Найти цитируемый пост)
Индейцы не обратили внимания на поток беженцев из Европы… Теперь они живут в резервациях. 
PM MAIL   Вверх
korob2001
Дата 6.11.2004, 13:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2871
Регистрация: 29.12.2002

Репутация: 6
Всего: 61



Спасибо. Но как я понял всё это работает под ...nix'ами, а я под виндой. ;)


--------------------
"Время проходит", - привыкли говорить вы по неверному пониманию. 
"Время стоит - проходите вы".
PM MAIL WWW ICQ MSN   Вверх
korob2001
Дата 7.11.2004, 00:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2871
Регистрация: 29.12.2002

Репутация: 6
Всего: 61



Всем спасибо за желание помочь.
Уже разобрался в доках к модулю Archive::Zip. Вобщем, всё великое в простом. Вот рабочий пример разорхивации ZIP архива:
Код

#!/usr/bin/perl
use strict;
use Archive::Zip;
my $zip = Archive::Zip->new("myarchive.zip"); # Создаём объект
$zip->extractTree(); # Разархивируем ZIP архив

Во как ;).

Может кому пригодится. Вот написал такой код:
Код

#!/usr/bin/perl -w
use strict;
use Archive::Zip;
my $fromDir = ".";
my $toDir = shift || 'ArchiveTemp';
$toDir =~ s/(?:\\|\/)$//;
mkdir( $toDir, 0744 ) or die "Can't create directory '$toDir': $!\n"
       unless -e $toDir;
my $count = 0;
opendir( DIR , $fromDir ) or die "Can't open directory '$fromDir/': $!\n";
 while ( my $file = readdir DIR ) {
         next unless $file =~ /\.zip$/i;
         my $zip = Archive::Zip->new( "$fromDir/$file" );
         $zip->extractTree();
         rename( "$fromDir/$file", "$toDir/$file" );
         print "-" x 70, "\n" if $count;
         print "File '$fromDir/$file' successfuly extracted.\n";
         $count++;
 }
closedir( DIR ) or die "Can't close directory '$fromDir': $!\n";
print "=" x 70, "\n";
my $lastString = "Total extracted $count file";
$lastString .= "s" if $count != 1;
print $lastString, "\n";

Для тех кто не понял, поясню:
Допустим у вас в каком-либо каталоге валяется большое кол-во архивов ZIP ( у меня их оказалось около 4000 ) и вам понадобилось, распаковать их все ( делать это вручную, занятие утомительное ;] ). Сохраняем в каталог с ZIP архивами этот код в файл unzip.pl и просто запускаем его на выполнение ( perl unzip.pl ). После чего будет создан каталог в который будут переноситься все, уже разархивированные ZIP архивы, а в текущем каталоге останутся только извлечённые файлы. Если возникнут вопросы по коду, пишите здесь.

Удачи. ;)

Это сообщение отредактировал(а) korob2001 - 7.11.2004, 01:08


--------------------
"Время проходит", - привыкли говорить вы по неверному пониманию. 
"Время стоит - проходите вы".
PM MAIL WWW ICQ MSN   Вверх
ElectricalStorm
Дата 9.11.2004, 17:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник Клуба
Сообщений: 547
Регистрация: 22.1.2004

Репутация: 1
Всего: 9



если у вас в архиве есть директории
и вам захочется разархивировать их в другую директорию не в текущую
?

;)


--------------------
Нужно знать инструмент, которым пользуешься
PM MAIL   Вверх
korob2001
Дата 9.11.2004, 23:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2871
Регистрация: 29.12.2002

Репутация: 6
Всего: 61



Думаю с помощью Archive::Zip это реально. Просто нужно с документауией разобраться до конца, а у меня с лэнгвичем не очень, да и инет отсутствует smile , но это всё временные трудности.
Так сложилось, что мне пришлось учить Нидерладский язык, да и то не могу им похвастаться smile Как-то не прёт меня учить языки, если это не языки программирования. ;)
Английский, знаю только школьную пограмму. Вот так и живу.

Вобщем, я хочу полностью изучить этот модуль, как дойду до этой темы, дам знать.

Но можно ведь воспользоваться возможностями самого Perl, правда прийдётся пожертвовать производительностью.
Вот что я имею ввиду:

1. Вырезаем имя самого ZIP архива, без расширения, и сохраняем его в переменную.
2. В каталоге в который будем разархивировать архив, создаём каталог с именем ZIP архива, которое сохранили в переменную в первом пункте.
3. Копируем текущий архив, в только что созданный каталог.
4. Переходим в него и там его разархивируем.
5. Удаляем ZIP архив из новой директории.

В конечном итоге получаем каталог, с вложенными каталогами, которые имеют аналогичные имена как и ZIP архивы. В каждом, этом каталоге будут размещены, все файлы и каталоги которые были в ZIP архиве.
Но, так как это нужно делать на каждой итерации, производительность понизится. smile

Electrical Storm - думаю у тебя не возникнет проблем с этой задачей ( потому код писать не стал ). Если знаешь сам, как это сделать с помощью модуля Archive::Zip или более производительней, напиши, буду очень признателен. Хотя в моём случае в архиве всего 1 файл, но вопрос действительно интересный, на будущее. Такая утилтка, под рукой, никогда не помешает. ;)

Сейчас скачаю себе этот модуль и дома пострадаю, может чего и выстадаю. ;)

Удачи.

Это сообщение отредактировал(а) korob2001 - 9.11.2004, 23:29


--------------------
"Время проходит", - привыкли говорить вы по неверному пониманию. 
"Время стоит - проходите вы".
PM MAIL WWW ICQ MSN   Вверх
ElectricalStorm
Дата 10.11.2004, 10:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник Клуба
Сообщений: 547
Регистрация: 22.1.2004

Репутация: 1
Всего: 9



Цитата

Если знаешь сам, как это сделать с помощью модуля Archive::Zip или более производительней, напиши, буду очень признателен


Конечно знаю поэтому и спросил ;) вдруг пригодиться .... smile

я не просто так спросил у этого модуля есть один не понятный момент
... он поразному рабоатет на FreeBSD и WinXP вот его я и имел ввиду...

когдато давно я просто столкнулся с этой проблемой ....

Код

# Вот такой вариант работает под  WinXP и не работает по FreeBSD
$zip->extractTree('', '', 'tmp');

# вот так помоему будет и там и там работать
$zip->extractTree( '', '/tmp');





--------------------
Нужно знать инструмент, которым пользуешься
PM MAIL   Вверх
korob2001
Дата 10.11.2004, 22:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2871
Регистрация: 29.12.2002

Репутация: 6
Всего: 61



Я вот вчера тоже пострадал, немного. ;) Тоже нашёл это дело, но оно почемуто не работает. Правда там, в первом параметре пердаётся имя файла из ZIP архива. Один раз вроде сработало, а попробовал пройти по всему дереву с помощью while. Вот туто я и обламался.
Выдаёт ошибку ввода/вывода. Указывает на каталог и пишет Access diened. smile
Права на каталог установлены "Только чтение" и что самое главное я не могу их изменить даже в самой системе. У винды бывают такие глюки. :[

Вот такие пироги. Ладно, повожусь еще ночьку. Завтра дам знать, что получилось.


--------------------
"Время проходит", - привыкли говорить вы по неверному пониманию. 
"Время стоит - проходите вы".
PM MAIL WWW ICQ MSN   Вверх
Guest
Дата 9.3.2005, 18:11 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Извините, я новичек, но почему нельзя было и имена файлов найти и сохранить в массив через
Код

@files=<*.zip>;

  Вверх
Bolt
Дата 9.3.2005, 19:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 21
Регистрация: 21.2.2005

Репутация: нет
Всего: нет



Цитата
... он поразному рабоатет на FreeBSD и WinXP вот его я и имел ввиду...

use File::Spec; «и будет вам счастье»
Цитата
но почему нельзя было и имена файлов найти и сохранить в массив через

вероятно потому, что
Цитата
Есть каталог, в котором примерно 4000 ZIP архивов

PM WWW ICQ   Вверх
korob2001
Дата 9.3.2005, 20:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2871
Регистрация: 29.12.2002

Репутация: 6
Всего: 61



Цитата

вероятно потому, что

Есть каталог, в котором примерно 4000 ZIP архивов

Абсолютно верно, просто glob не вернёт имена всех файлов текущего каталога, если файлов много. Можно было конечно же заюзать системную коммаду, но в таком случае мы привязываем сами сабя к определённой оболочке. smile В данном случае самым лучший вариант это opendir, readdir, closedir.


--------------------
"Время проходит", - привыкли говорить вы по неверному пониманию. 
"Время стоит - проходите вы".
PM MAIL WWW ICQ MSN   Вверх
Bolt
Дата 10.3.2005, 13:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 21
Регистрация: 21.2.2005

Репутация: нет
Всего: нет



Цитата
мы привязываем сами сабя к определённой оболочке

если речь идет о
Код
@zips=grep (/\.zip/i,readdir DIR);

то это работает везде т.к. grep - встроенная функция.
а вот про glob - спорно. smile
при вызове glob автоматоически подгружается модуль File::Glob... Начиная с версии Perl 5.6, до этой версии использовался внешний процесс (csh).
т.о. use File::Glob ':glob'; #используем glob из POSIX, а не csh...
smile
А я имел ввиду, цитируя, лишь количество файлов: массив получается довольно ёмкий, как ни крути, и держать его в памяти ни есть хорошим стилем программирования. Кстати, относительно отличий исполнения под win* и *nix: одно из них заключено в том, что под win* стоило бы присваивать значения undef объёмным массивам и хэшам в конце программы, дабы явно освободить память. imho.
PM WWW ICQ   Вверх
korob2001
Дата 10.3.2005, 19:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2871
Регистрация: 29.12.2002

Репутация: 6
Всего: 61



Ты считаешь, что под виндой память не освобождается после того, как программа завершает свою работу????
Насколько я знаю, то undef( @arr ), применяется в том случае, если программа продолжает работу, а массив @arr больше не нужен и нужно вернуть в текущий момет всю занимаемую им память в пул пямяти процесса, но далеко не все системы поддерживают это.
Цитата

то это работает везде т.к. grep - встроенная функция.
а вот про glob - спорно.

Нет, речь идёт о таком способе:
Код

#!/usr/bin/perl -w
use strict;
my @arr = glob("*.zip");
print join("\n", @arr);

или
Код

#!/usr/bin/perl -w
use strict;
my @arr = <*.zip>;
print join("\n", @arr);

Но и с grep мы грузим память, потому как grep вернёт список файлов.

Это сообщение отредактировал(а) korob2001 - 10.3.2005, 19:50


--------------------
"Время проходит", - привыкли говорить вы по неверному пониманию. 
"Время стоит - проходите вы".
PM MAIL WWW ICQ MSN   Вверх
Ramirez
Дата 13.4.2005, 01:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 305
Регистрация: 18.1.2005
Где: Moscow, ExUSSR

Репутация: нет
Всего: 5



Пародон за оффтоп: в винде, если есть WinRAR, выделяются все архивы, потом правый клик, пункт: распаковать ВСЕ аривы в ... =) smile
PM ICQ   Вверх
korob2001
Дата 13.4.2005, 06:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2871
Регистрация: 29.12.2002

Репутация: 6
Всего: 61



Эх Ramirez smile , дело не в WinRAR'e. Хотелось самому распаковать. Иногда и велосипеды полезно изобретать. smile


--------------------
"Время проходит", - привыкли говорить вы по неверному пониманию. 
"Время стоит - проходите вы".
PM MAIL WWW ICQ MSN   Вверх
Guest123
Дата 23.6.2005, 20:13 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











А может Вы подскажете как вывести имена файлов (и их размер) ZIP архива не ражимая его? т.е. на лету прочесть??
perldoc Archive::ZIP читал - так ничего и не получилось внятного smile smile
можь подскажите че??
  Вверх
Guest
Дата 13.10.2005, 22:00 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Цитата
$zip->extractTree();

Не катит. Т.е. вообще такого нет в мануале к zip!

Разархивирю так:
$zip=Archive::Zip->new("file.zip");
$zip->extractMember("unzip.dat","unzip_new.dat");
  Вверх
korob2001
Дата 14.10.2005, 01:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2871
Регистрация: 29.12.2002

Репутация: 6
Всего: 61



Guest - Как так нет? Вот тебе часть документации, где описывается метод extractTree().
perldoc Archive::Zip
Цитата

    $zip->extractTree()
    $zip->extractTree( $root )
    $zip->extractTree( $root, $dest )
    $zip->extractTree( $root, $dest, $volume )
        If you don't give any arguments at all, will extract all the files
        in the zip with their original names.

        If you supply one argument for $root, "extractTree" will extract all
        the members whose names start with $root into the current directory,
        stripping off $root first. $root is in Zip (Unix) format. For
        instance,

          $zip->extractTree( 'a' );

        when applied to a zip containing the files: a/x a/b/c ax/d/e d/e
        will extract:

        a/x as ./x

        a/b/c as ./b/c

        If you give two arguments, "extractTree" extracts all the members
        whose names start with $root. It will translate $root into $dest to
        construct the destination file name. $root and $dest are in Zip
        (Unix) format. For instance,

          $zip->extractTree( 'a', 'd/e' );

        when applied to a zip containing the files: a/x a/b/c ax/d/e d/e
        will extract:

        a/x to d/e/x

        a/b/c to d/e/b/c and ignore ax/d/e and d/e

        If you give three arguments, "extractTree" extracts all the members
        whose names start with $root. It will translate $root into $dest to
        construct the destination file name, and then it will convert to
        local file system format, using $volume as the name of the
        destination volume.

        $root and $dest are in Zip (Unix) format.

        $volume is in local file system format.

        For instance, under Windows,

          $zip->extractTree( 'a', 'd/e', 'f:' );

        when applied to a zip containing the files: a/x a/b/c ax/d/e d/e
        will extract:

        a/x to f:d/e/x

        a/b/c to f:d/e/b/c and ignore ax/d/e and d/e

        If you want absolute paths (the prior example used paths relative to
        the current directory on the destination volume, you can specify
        these in $dest:

          $zip->extractTree( 'a', '/d/e', 'f:' );

        when applied to a zip containing the files: a/x a/b/c ax/d/e d/e
        will extract:

        a/x to f:\d\e\x

        a/b/c to f:\d\e\b\c and ignore ax/d/e and d/e



--------------------
"Время проходит", - привыкли говорить вы по неверному пониманию. 
"Время стоит - проходите вы".
PM MAIL WWW ICQ MSN   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Perl: Системное программирование"
korob2001
sharq
  • В этом разделе обсуждаются вопросы относящиеся только к системному программированию на Perl
  • Если ваш вопрос не относится к системному или CGI программированию, задавайте его в общем разделе
  • Если ваш вопрос относится к CGI программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O'REILLY, The source for Perl
  • Справочное руководство "Установка perl-модулей", можно скачать здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Perl: Системное программирование | Следующая тема »


 




[ Время генерации скрипта: 0.0609 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.