Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Re^3: rename zip files and folders inside zip files

by toolic (Bishop)
on Aug 27, 2015 at 14:33 UTC ( [id://1140212]=note: print w/replies, xml ) Need Help??


in reply to Re^2: rename zip files and folders inside zip files
in thread rename zip files and folders inside zip files

From the POD:
endRead() Must be called to close files, etc.

Replies are listed 'Best First'.
Re^4: rename zip files and folders inside zip files
by mariog (Acolyte) on Aug 31, 2015 at 10:19 UTC
    I try to do this:
    #!/usr/bin/perl -w use warnings; use strict; use Archive::Zip qw( :ERROR_CODES ); my @files; @files = <ATP.xxx*.zip>; foreach my $file (@files){ my $zip = Archive::Zip->new(); $zip->read($file) == AZ_OK or die "read error $!"; $zip->endRead($file); $file=~ s{\.[^.]+$}{}; my $m1 = $zip->memberNamed($file); $file=~s/^.{4}//s; $m1->fileName($file); $zip->overwriteAs("$file.zip") == AZ_OK or die "write error $!\n"; }
    it tells me: Can't locate object method "endRead" via package "Archive::Zip::Archive" at ./ziprenamer2.pl line 12. if I do this:
    #!/usr/bin/perl -w use warnings; use strict; use Archive::Zip qw( :ERROR_CODES ); my @files; @files = <ATP.xxx*.zip>; foreach my $file (@files){ my $zip = Archive::Zip->new(); $zip->read($file) == AZ_OK or die "read error $!"; #$zip->endRead($file); $file=~ s{\.[^.]+$}{}; my $m1 = $zip->memberNamed($file); $file=~s/^.{4}//s; $m1->fileName($file); $m1->endRead(); $zip->overwriteAs("$file.zip") == AZ_OK or die "write error $!\n"; }
    I get the same error as before and too many files open
    at /usr/share/perl5/Archive/Zip/FileMember.pm line 40 Archive::Zip::FileMember::_openFile('Archive::Zip::ZipFileMemb +er=HASH(0x257b610)') called at /usr/share/perl5/Archive/Zip/FileMembe +r.pm line 30 Archive::Zip::FileMember::fh('Archive::Zip::ZipFileMember=HASH +(0x257b610)') called at /usr/share/perl5/Archive/Zip/ZipFileMember.pm + line 381 Archive::Zip::ZipFileMember::rewindData('Archive::Zip::ZipFile +Member=HASH(0x257b610)') called at /usr/share/perl5/Archive/Zip/Membe +r.pm line 1063 Archive::Zip::Member::_writeToFileHandle('Archive::Zip::ZipFil +eMember=HASH(0x257b610)', 'IO::File=GLOB(0x257ba60)', 1, 0) called at + /usr/share/perl5/Archive/Zip/Archive.pm line 420 Archive::Zip::Archive::writeToFileHandle('Archive::Zip::Archiv +e=HASH(0x242d8f8)', 'IO::File=GLOB(0x257ba60)') called at /usr/share/ +perl5/Archive/Zip/Archive.pm line 456 Archive::Zip::Archive::overwriteAs('Archive::Zip::Archive=HASH +(0x242d8f8)', 'ROUTINGS.D150313.T1600.zip') called at ./ziprenamer2.p +l line 17 Can't write to /tmp/2PMKA29PUY.zip at ./ziprenamer2.pl line 17 write error Too many open files
    and only about 1000 files are processed Note I just have to do it once.. the next times I only have to rename the last one arrived.. it will be set as a cron job.

    thank you.

      Thanks for showing these versions. I tried my own approach to do the same thing, and I got the same problem you did. Here's my code:
      #!/usr/bin/perl use strict; use Archive::Zip; my $Usage = "$0 zip_path\n"; die $Usage unless ( @ARGV == 1 and -d $ARGV[0] ); chdir( $ARGV[0] ) or die "chdir $ARGV[0]: $!\n"; my @files = <*.zip>; for my $zipname ( @files ) { # next statement reads the zip file: my $newname = rename_contents( $zipname ); rename( $zipname, $newname ); } sub rename_contents { my ( $zipname ) = @_; my $zip = Archive::Zip->new( $zipname ) or die "can't read $zipname: $!\n"; ( my $dataname = $zipname ) =~ s/\.zip$//; my $data = $zip->removeMember( $dataname ); ( my $newdataname = $dataname ) =~ s/^.{4}//; $data->fileName( $newdataname ); $zip->addMember( $data ); $zip->overwrite(); return( "$newdataname.zip" ); }
      I used a subroutine for all the Archive::Zip activity, in the hope that the scoping would force each iteration to leave a clean slate (because the $zip object should be destroyed when it goes out of scope). But since I got "too many files open", it must be the case that the zip object is not getting cleaned up. I'd call this a bug, either in the module itself, or else in whatever zip library it links to.

      Better to use IO::Compress::Zip and IO::Uncompress:Unzip -- especially since these are "core" modules, part of the standard Perl distro.

      I tried the code below, it didn't fail, and it changed the name of each zip file and of the data file in each zip. (It assumes there's only one data file per zip.)

      #!/usr/bin/perl use strict; use IO::Compress::Zip qw/zip $ZipError/; use IO::Uncompress::Unzip qw/unzip $UnzipError/; my $Usage = "$0 zip_path\n"; die $Usage unless ( @ARGV == 1 and -d $ARGV[0] ); chdir( $ARGV[0] ) or die "chdir $ARGV[0]: $!\n"; my @files = <*.zip>; for my $zipname ( @files ) { my $newname = rename_contents( $zipname ); rename( $zipname, $newname ); } sub rename_contents { my ( $zipname ) = @_; my $data; unzip( $zipname => \$data ) or die "$zipname read failed: $UnzipError\n"; ( my $newname = $zipname ) =~ s/^.{4}//; $newname =~ s/\.zip$//; my $fz = new IO::Compress::Zip( $zipname, Name => $newname ) or die "$zipname open-for-write failed: $ZipError\n"; $fz->write( $data ) or die "$zipname write failed: $ZipError\n"; return( "$newname.zip" ); }

      UPDATE: I should have mentioned: Archive::Zip on my (macosx) laptop hit "too many files open" after less than 300 files; I'm impressed that you were able to get as far as 1000.

Re^4: rename zip files and folders inside zip files
by mariog (Acolyte) on Aug 28, 2015 at 11:55 UTC
    Hello, I have been trying but it does not work. and the endRead ignored.. any ideas how to put it? I am sorry if the question is trivial.
      At this point, you would need to show the code as it currently stands (so we know where you've put the "endRead" call), and it would help to tell us what the error message is. Don't tell is what you think it did (or didn't do) - show us what it actually did (copy/paste the error messages).
        I try to do this:
        #!/usr/bin/perl -w use warnings; use strict; use Archive::Zip qw( :ERROR_CODES ); my @files; @files = <ATP.xxx*.zip>; foreach my $file (@files){ my $zip = Archive::Zip->new(); $zip->read($file) == AZ_OK or die "read error $!"; $zip->endRead($file); $file=~ s{\.[^.]+$}{}; my $m1 = $zip->memberNamed($file); $file=~s/^.{4}//s; $m1->fileName($file); $zip->overwriteAs("$file.zip") == AZ_OK or die "write error $!\n"; }
        it tells me: Can't locate object method "endRead" via package "Archive::Zip::Archive" at ./ziprenamer2.pl line 12. if I do this:
        #!/usr/bin/perl -w use warnings; use strict; use Archive::Zip qw( :ERROR_CODES ); my @files; @files = <ATP.xxx*.zip>; foreach my $file (@files){ my $zip = Archive::Zip->new(); $zip->read($file) == AZ_OK or die "read error $!"; #$zip->endRead($file); $file=~ s{\.[^.]+$}{}; my $m1 = $zip->memberNamed($file); $file=~s/^.{4}//s; $m1->fileName($file); $m1->endRead(); $zip->overwriteAs("$file.zip") == AZ_OK or die "write error $!\n"; }
        I get the same error as before and too many files open
        at /usr/share/perl5/Archive/Zip/FileMember.pm line 40 Archive::Zip::FileMember::_openFile('Archive::Zip::ZipFileMemb +er=HASH(0x257b610)') called at /usr/share/perl5/Archive/Zip/FileMembe +r.pm line 30 Archive::Zip::FileMember::fh('Archive::Zip::ZipFileMember=HASH +(0x257b610)') called at /usr/share/perl5/Archive/Zip/ZipFileMember.pm + line 381 Archive::Zip::ZipFileMember::rewindData('Archive::Zip::ZipFile +Member=HASH(0x257b610)') called at /usr/share/perl5/Archive/Zip/Membe +r.pm line 1063 Archive::Zip::Member::_writeToFileHandle('Archive::Zip::ZipFil +eMember=HASH(0x257b610)', 'IO::File=GLOB(0x257ba60)', 1, 0) called at + /usr/share/perl5/Archive/Zip/Archive.pm line 420 Archive::Zip::Archive::writeToFileHandle('Archive::Zip::Archiv +e=HASH(0x242d8f8)', 'IO::File=GLOB(0x257ba60)') called at /usr/share/ +perl5/Archive/Zip/Archive.pm line 456 Archive::Zip::Archive::overwriteAs('Archive::Zip::Archive=HASH +(0x242d8f8)', 'ROUTINGS.D150313.T1600.zip') called at ./ziprenamer2.p +l line 17 Can't write to /tmp/2PMKA29PUY.zip at ./ziprenamer2.pl line 17 write error Too many open files
        and only about 1000 files are processed Note I just have to do it once.. the next times I only have to rename the last one arrived.. it will be set as a cron job.

        thank you.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1140212]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others learning in the Monastery: (4)
As of 2024-04-26 01:13 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found