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.


In reply to Re^5: rename zip files and folders inside zip files by graff
in thread rename zip files and folders inside zip files by mariog

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.