user3781528 user3781528 - 20 days ago 4x
Perl Question

Unzip folders recursively in a directory (preserving the folder name)

I'm looking for a way to unzip multiple folder (*.zip) in a specified directory and preserving the name of each folder. I would prefer this to be a part of a Perl script. Do I need to use shell? Please suggest a way to accomplish this.

I've tried the following shell script that is called from the main Perl script:
but it only un-zipped the first folder and didn't preserve the folder name.

elif [[ "$process" == "unzip" ]];then
cd $datapath
cd $home
for ff in $folders; do
echo $sname
if [ ! -f $sname ];then
cd $datapath
cd $sname
cmd2="unzip -n '*.zip'"
echo $cmd2
cmd2=`unzip -n '*.zip'`
echo $cmd2
cmd3="gunzip -f *.gz"
echo $cmd3
cmd3=`gunzip -f *.gz`
echo $cmd3
cd $home

in Perl script I call:

my $cmd2 = `perl /data/test_all_runs unzip`; print "$cmd2";




From the comments it got clear that you have some *.zip files in the directory /data/test_all_runs/test and you want them to be extracted to subdirectories with the zipfile's names below that directory. For example:





If I understood that right, the following code can help:

#!/usr/bin/env perl

use strict;
use warnings;

sub extract_zips_to_their_folders
    my $source_dir = shift;

    # iterate over all *.zip files in $source_dir:
    while( my $zipfile = <$source_dir/*.zip> ) {

        # remove '.zip' from $zipfile and store the result as $tgt_dir.
        # If $zipfile is e.g. '/data/test_all_runs/test/',
        # then $tgt_dir will be '/data/test_all_runs/test/a'.
        (my $tgt_dir = $zipfile) =~ s/\.zip$//;

        # Call 'unzip' with option '-d $tgt_dir', i.e. unzip
        # the archive to the directory with the same name.
        # 'unzip' will create the directory for you.         
        system("unzip $zipfile -d $tgt_dir");

extract_zips_to_their_folders( '/data/test_all_runs/test' );

It calls the external command unzip. As noted in another answer, there are also Perl modules available to avoid such external calls.