Skip to content

Instantly share code, notes, and snippets.

@akirad
Last active December 19, 2015 10:59
Show Gist options
  • Save akirad/5944476 to your computer and use it in GitHub Desktop.
Save akirad/5944476 to your computer and use it in GitHub Desktop.
Specified a dir as a argument, this script extracts archive files(zip/ear/war/jar files) in the dir recursively. It means if a zip file contains another zip file, both zip files are extracted. Then, if "-d" option is specified, the original archive files are removed.
use strict;
use warnings;
use Archive::Zip;
use File::Basename;
use Getopt::Long;
my $DEF_OF_ARC = '(\.zip$)|(\.jar$)|(\.war$)|(\.ear$)|(\.sar$)';
my $deleteArchiveFile;
GetOptions(
'deleteArchiveFile' => \$deleteArchiveFile,
);
my $dir = $ARGV[0];
if(! -d $dir){
die "Invalid argument.";
}
$dir =~ s|\\|/|g; # Just in case, change '\' to '/' in the Windows path.
extract($dir);
sub extract{
my $dir = shift;
opendir(my $dh, $dir);
my @fileList = readdir($dh);
closedir($dh);
foreach my $file (sort @fileList){
if($file =~ /^\.{1,2}$/){
next;
}
if(($file =~ /$DEF_OF_ARC/) && (-f "$dir/$file")){
extractZip("$dir/$file");
if(defined($deleteArchiveFile)){
unlink("$dir/$file");
}
}
if(-d "$dir/$file"){
extract("$dir/$file");
}
}
}
sub extractZip{
my $zip = shift;
my $dir = dirname($zip);
my $archive = Archive::Zip->new($zip);
my @members = $archive->memberNames();
foreach my $member (@members) {
$archive->extractMember($member, "$dir/$member");
if(($member =~ /$DEF_OF_ARC/) && (-f "$dir/$member")){
extractZip("$dir/$member");
if(defined($deleteArchiveFile)){
unlink("$dir/$member");
}
}
if(-d $member){
extract("$dir/$member");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment