user3781528 - 10 months ago 74
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
folders="$(ls)" cd$home
for ff in $folders; do sname=$ff
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 fi done  in Perl script I call: my$cmd2 = perl MDL_unzip_annotate.sh /data/test_all_runs unzip;  print "$cmd2"; **Before:** \data\test_all_runs\SN2-63-OFA_Val_5_Chip2\Test1.zip \data\test_all_runs\SN2-63-OFA_Val_5_Chip2\Test2.zip **After:** \data\test_all_runs\SN2-63-OFA_Val_5_Chip2\Test1\text_stuff.txt \data\test_all_runs\SN2-63-OFA_Val_5_Chip2\Test2\text-stuff2.txt  Answer Source 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: Before: /data/test_all_runs/test/a.zip /data/test_all_runs/test/b.zip  After: /data/test_all_runs/test/a.zip /data/test_all_runs/test/a/file1_from_a.txt /data/test_all_runs/test/a/file2_from_a.txt /data/test_all_runs/test/a/file3_from_a.txt /data/test_all_runs/test/b.zip /data/test_all_runs/test/b/file1_from_b.txt /data/test_all_runs/test/b/file2_from_b.txt /data/test_all_runs/test/b/file3_from_b.txt  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/a.zip',
# 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.