Thuan Nguyen
Thuan Nguyen

Reputation: 33

(unix shell scripting) Unzip multiple zip files, rename unzipped file following zip file name

I have multiple zip files like this example:

759198298412.zip
----i love you.pdf
----forever and one.txt
----today and tomorrow.docs
48891721241592__5123.zip
----whatever it is.pdf
5717273_616.zip
----igotit.txt
----thank you very much.mp3    

I am trying to make a script to unzip the zip files, and rename the unzipped files to the zip file name. like this output:

759198298412.pdf
759198298412.txt
759198298412.docs

48891721241592__5123.pdf

5717273_616.txt
5717273_616mp3

I found this script below, but it doesn't work for me because my files have space and i have multiple files in a zip file.

for i in *.zip
do 
n=$(unzip -lqq $i | awk '{print $NF}')
e=${n#*.}
unzip $i && mv $n ${i%%_*}".$e"
done    

Please help! thank you

Upvotes: 3

Views: 20153

Answers (3)

scht_r
scht_r

Reputation: 21

for zip in *.zip; do
    zip_filename="${zip%%.*}"
    unzip "${zip}" -d "${zip_filename}-dir"

    for file in "${zip_filename}-dir"/*.*; do
        extension="${file##*.}"         
        new_name="${zip_filename}.${extension}"
        mv "${file}" "${new_name}"
    done

    rmdir "${zip_filename}-dir"
    # delete the zip file
    # rm "${zip}"
done

The script basically just unzips the files to a new temporary directory, it then renames all the files in the new directory and moves them out of the directory, and finally it deletes the temporary directory.

Upvotes: 2

Beggarman
Beggarman

Reputation: 896

A few small changes:

  1. Quote variables to deal with the spaces in file names.
  2. Use unzip -Z -1 to get a listing of the files in the archive to avoid using awk (which is printing just the final part of names with spaces).
  3. Since unzip -Z -1 splits records by line, we set the IFS to '\n' so records split properly.
  4. Replace the underscore in the move to a dot so .zip extension is removed.

New script is:

IFS=$'\n'
for i in *.zip
do
   for n in $(unzip -Z -1 "$i"); do 
       echo "$i - $n"
       e=${n#*.}
       unzip "$i" "$n" && mv "$n" ${i%%.*}".$e"
   done
done

Note that this script assumes you've only got one of each file extension in your zip. If that's not true, you'll need to handle duplicate files in some fashion.

Output after running:

48891721241592__5123.pdf  
48891721241592__5123.zip  
759198298412.docs  
759198298412.pdf  
759198298412.txt  
759198298412.zip

Upvotes: 1

Etan Reisner
Etan Reisner

Reputation: 81052

for i in *.zip; do
    mkdir "$i-dir"
    cd "$i-dir"
    unzip "../$i"
    for j in *; do
        mv "$j" "$i.${j##*.}"
    done
    cd ..
done

If dropping everything after the first underscore in the file name is important than the mv line should be:

mv "$j" "${i%%_*}.${j##*.}"

And to have that dropping work even when no underscore is present in the zip file name use:

i=${i%.zip}; mv "$j" "${i%%_*}.${j##*.}"

And to keep the files all in the top-level directory prefix ../ to the mv target filename.

Upvotes: 5

Related Questions