34

How do I compress every file in a directory into its own tar whilst preserving the name for each file?

i.e. file1.out file2.out

-->

file1.out.tar.gz file2.out.tar.gz

3 Answers 3

77

Putting every file into a separate tar file doesn't make any sense in this scenario. You can use gzip to compress them directly:

gzip *

will result in file1.out.gz, file2.out.gz etc.

You would use tar only if you would need a compressed archive as a single file.

If you ineed need a tar archive for every file, you can create it like so:

for i in *; do tar -czf $i.tar.gz $i; done
4
  • 7
    +1 - There is no reason to create a tar (Tape ARchive) for a single file. Just compress what you want to compress - the result will be marginally smaller, and make infinitely more sense to people extracting the files.
    – voretaq7
    Feb 5, 2012 at 20:28
  • To tar each individual subdirectory (only one level deep) and remove the original: find . -maxdepth 1 -type d ! -path . | while read a_dir; do tar -zcvf ${a_dir}.tgz ${a_dir} --remove-files; done
    – xb.
    Jul 13, 2016 at 18:21
  • (can't edit my comment above after 5 min) A simpler/safer version: find . -maxdepth 1 -mindepth 1 -type d -exec tar -zcvf {}.tgz {} --remove-files \;
    – xb.
    Jul 13, 2016 at 18:37
  • And gzip -d * to unzip .gz files
    – igonejack
    Apr 27, 2021 at 2:43
11

To build on @SvenW's answer (which will only work on the current directory), if you have a HUGE number of files or want to do it on a recursive directory structure you can also use

find . -type f -exec gzip \{\} \;

and if you need to put the output into a different directory (in this example, ../target) and don't want to remove the originals, you can do something like:

find . -type f -print | while read fname ; do
    mkdir -p "../target/`dirname \"$fname\"`"
    gzip -c "$fname" > "../target/$fname.gz"
done
6
  • 1
    find . -type f -exec gzip {} \; will be sufficient. The second code will fail with filenames containing spaces and the like. Feb 6, 2012 at 2:29
  • Some shells don't like bare {}s, and the second one does something markedly different than the first (and I was aware of the spacing issues but that is kind of tricky to deal with).
    – fluffy
    Feb 6, 2012 at 3:07
  • If you know such a shell, I invite you to answer my question over here: unix.stackexchange.com/questions/8647/… . Nobody was able to name something which is today in use so far. If you are aware of a risk of your answer, it might be a good idea to name it in your answer. Feb 6, 2012 at 4:20
  • @userunknown I was brought up on (t)csh, which had quite a lot of trouble with unescaped curly braces at one time, although it doesn't appear to anymore (but I still escape {} as a force of habit). Others have already posted those as answers to your question, however.
    – fluffy
    Feb 6, 2012 at 6:55
  • Or, to compress all non-binary files: find . -type f -exec grep -Iq . {} \; -and -exec gzip {} \;
    – xb.
    Jul 13, 2016 at 15:30
1

Try this one:

#!/bin/bash
for fich in *; do
    if [ "$fich" != "*" ] ; then
        gzip -9 -c $fich > $fich.tar.gz
        \mv $fich.tar.gz $fich
    fi
done

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.