0

I have a task to reach the last file in long line of nested zip archives. They go like this:

3301.zip | 3300.zip | 3299.zip | ... | 1.zip

Basically, I have to extract one archive from another 3300 times in order to reach the file within 1.zip.

I have searched for ways to do this, but maybe my search terms weren't right or I missed something. I tried "reach last file nested zips", "extract nested zips". My working environment is Linux and I tried several Terminal commands and tools. Nothing did what I wanted.

2 Answers2

2

If the zip files are all sequentially numbered, then you can unpack them all with a simple one-liner:

for i in {3301..1} ; do f="$i.zip" ; unzip -q "$f" ; rm "$f" ; done 

And should you ever need it, the packing can be done with a very similar one-liner:

f="flag.txt" ; for i in {1..3301} ; do g="$i.zip" ; zip -q $g $f ; rm $f ; f="$g" ; done
r3mainer
  • 23,981
  • 3
  • 51
  • 88
0

Here is a Perl script, nested-unzip that walks through nested zip files and prints the contents if the innermost zip file.

#!/usr/bin/perl

use strict;
use warnings;

use Archive::Zip::SimpleZip qw($SimpleZipError) ;
use File::Basename;
use Text::Glob;

sub walk
{
    my $zip = shift;
    my $path = shift ;
    my $depth = shift // 1 ;

    my $indent = '  ' x $depth;
    for my $p (<$path/*>)
    {
        my $filename = basename $p;
        my $dir = dirname $p;

        if (-d $p)
        {
            print $indent . "$filename [as $filename.zip]\n";

            my $newfh = $zip->openMember(Name => $filename . ".zip");

            my $newzip = new Archive::Zip::SimpleZip $newfh, Stream => 1
                    or die "Cannot create zip file '$filename.zip': $SimpleZipError\n" ;

            walk($newzip, $p, $depth + 1);
            $newzip->close();
        }
        else
        {
            print $indent . "$filename\n";
            $zip->add($p, Name => $filename);
        }
    }
}

my $zipfile = $ARGV[0];
my $path = $ARGV[1] ;

my $zip = new Archive::Zip::SimpleZip $zipfile
        or die "Cannot create zip file '$zipfile': $SimpleZipError\n" ;


print "$path\n";
walk($zip, $path);

create a nested zip file to play with

$ echo hello >hello.txt
$ zip 1.zip hello.txt 
$ zip 2.zip 1.zip
$ zip 3.zip 2.zip

and finally running the script

$ perl nested-unzip 3.zip 
3.zip
  2.zip
    1.zip
      hello.txt
pmqs
  • 3,066
  • 2
  • 13
  • 22