I have several ZIP and RAR archives where the filenames inside the archive are scrambled and they contain invalid filesystem characters like ?-s *-s or !-s or very long file and directory names that confuse the usual archiver tools or they simply fail to create the file. Since only the content matters I would just like to extract the files in these archives into a single directory in a flat structure with generic names like file0, file1, file2, etc... What's the simplest way to do that?

  • 1
    Maybe you can code a script in a language with a Zip library (such as Python) which will loop over the entries of the zipfile to extract them under a new name?
    – lgeorget
    Jan 28, 2016 at 14:01
  • You're saying that the filenames inside the ZIP are corrupted? Or that the ZIP archive filename itself is corrupted?
    – roaima
    Jan 28, 2016 at 14:22
  • @igeorget If that's the simlplest way. Though I have never programmed in Python yet.
    – Calmarius
    Jan 28, 2016 at 14:22
  • @roaima The filenames inside the archive are corrupted.
    – Calmarius
    Jan 28, 2016 at 14:23
  • 2
    See also rename files in a zip archive before extracting (there'a python solution there...) Jan 28, 2016 at 14:44

1 Answer 1


There is a Perl script written by Daniel S. Sterling available at https://gist.github.com/eqhmcow/5389877 (referenced from IO::Uncompress::Unzip) that looks like it could almost do what you need.

  • Change line 46 to read my $status, $filenumber = 0;
  • Comment lines 52-54 (put # at the beginning of each line)
  • Change line 61 to read my $destfile = "file" . $filenumber++;

The entire script, with these modifications, is presented below for reference:

# example perl code, this may not actually run without tweaking, especially on Windows

use strict;
use warnings;

IO::Uncompress::Unzip works great to process zip files; but, it doesn't include a routine to actually
extract an entire zip file.
Other modules like Archive::Zip include their own unzip routines, which aren't as robust as IO::Uncompress::Unzip;
eg. they don't work on zip64 archive files.
So, the following is code to actually use IO::Uncompress::Unzip to extract a zip file.

use File::Spec::Functions qw(splitpath);
use IO::File;
use IO::Uncompress::Unzip qw($UnzipError);
use File::Path qw(mkpath);

# example code to call unzip:

=head2 unzip
Extract a zip file, using IO::Uncompress::Unzip.
Arguments: file to extract, destination path
    unzip('stuff.zip', '/tmp/unzipped');

sub unzip {
    my ($file, $dest) = @_;

    die 'Need a file argument' unless defined $file;
    $dest = "." unless defined $dest;

    my $u = IO::Uncompress::Unzip->new($file)
        or die "Cannot open $file: $UnzipError";

    my $status, $filenumber = 0;
    for ($status = 1; $status > 0; $status = $u->nextStream()) {
        my $header = $u->getHeaderInfo();
        my (undef, $path, $name) = splitpath($header->{Name});
        my $destdir = "$dest/$path";

        # unless (-d $destdir) {
        #     mkpath($destdir) or die "Couldn't mkdir $destdir: $!";
        # }

        if ($name =~ m!/$!) {
            last if $status < 0;

        my $destfile = "file" . $filenumber++;
        my $buff;
        my $fh = IO::File->new($destfile, "w")
            or die "Couldn't write to $destfile: $!";
        while (($status = $u->read($buff)) > 0) {
        my $stored_time = $header->{'Time'};
        utime ($stored_time, $stored_time, $destfile)
            or die "Couldn't touch $destfile: $!";

    die "Error processing $file: $!\n"
        if $status < 0 ;



Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.