How to compress multiple folders, each into its own zip archive?

24,070

Solution 1

for i in *
do
[ -d "$i" ] && zip -r "$i.zip" "$i"
done

You walk through all the directories and create zip for each of them.

Or even more concise:

for i in */; do zip -r "${i%/}.zip" "$i"; done

(thanks to damienfrancois for suggestion).

Solution 2

here

for i in */; do tar -czvf "${i%/}.tar.gz" "$i"; done

Solution 3

Consider using xz algorithm if you require smaller output (at the cost of longer process):

for d in */ ; do
    outName=$d;
    outName=${outName// /\-};
    outName=${outName//[!0-9a-z-]};
    dirName=$d;
    dirName=${dirName//\/}
    tar -c "$dirName" | xz -e > $outName.tar.xz
done

This code will sanitise folder names and produce .tar.xz for every folder in the current directory.

Share:
24,070
Villi Magg
Author by

Villi Magg

Updated on February 22, 2021

Comments

  • Villi Magg
    Villi Magg about 3 years

    So I want to create a script that enables me to compresses each folder into its own zip archive and not into a one big zip file.

    As an example, I've got a directory:

    + MyDirectory/
    | |
    | + Folder_01/
    | |
    | + Folder_02/
    | |
    | + Folder_03/
    |
    

    When I'm done running the script under MyDirectory then I would have a zip file of each Folder which is inside MyDirectory: Folder_01.zip, Folder_02.zip and Folder_03.zip. I know some BASH but this is something I can't figure out.

    How can this be done?

    Kind regards.

  • damienfrancois
    damienfrancois over 10 years
    you can avoid the [ -d "$i" ] && part with for i in */
  • Igor Chubin
    Igor Chubin over 10 years
    @damienfrancois: Superhint! Thank you!!
  • damienfrancois
    damienfrancois over 10 years
    though you have to ${i%/}.zip afterwards to get rid of the trailing / in this particular case
  • Villi Magg
    Villi Magg over 10 years
    Thank you! If making this an executable to store under bin/ directory and to useful to do compression operations where you'd provide options like */ for directories, or *.* for files, or even *.jpeg if you only want to compress .jpeg files. How would you write the code so that you'd only need to type f.ex. compress */, or compress *.jpeg? To take it even further the script could be written so that you could provide options like -a/--all for compressing all into one big zip archive, and -e/--each for compressing each into its own zip file, etc... Thank you! :)
  • Igor Chubin
    Igor Chubin over 10 years
    @VilliMagg: That's right, but you must note that it is the shell who expands file globs, so your script will not get all these *.jpeg etc unless you escape them with ''
  • Villi Magg
    Villi Magg over 10 years
    @IgorChubin: So it would be necessary to type compress "*.jpeg"?
  • Igor Chubin
    Igor Chubin over 10 years
    @VilliMagg: Yes, if you want script to get the star and the expanded list.
  • Bouncner
    Bouncner almost 5 years
    You might want to add a note that -e increases the time for compression significantly and should more or less only be used for archiving.
  • Nasri Najib
    Nasri Najib over 4 years
    @damienfrancois - Great 1-liner: for i in */; do zip -r "${i%/}.zip" "$i"; done It works when I tested on mobaxterm v11 (after installing zip utility) in windows 10. Thank you!
  • Because i hate myself
    Because i hate myself almost 2 years
    @IgorChubin how can i give them password , same or a different