How can I recursively bzip2 all files that aren't bzipped?

How can I recursively bzip2 all files that do not end with the .bz2 extension in Linux?


find is your friend. I reckon the following ought to do it:

find <target_dir> -not -name \*.bz2 -exec bzip2 \{\} \;

i.e. if the dir where the files you want to bzip are is /var/log/blah it would be:

find /var/log/blah -not -name \*.bz2 -exec bzip2 \{\} \;

Off the top of my head (sorry, don't have a shell handy to test quoting etc.):

for _t in `find . -print |grep -v -E "\.bz$"`; do bzip2 -9 $_t && echo OK $_t || echo FAIL $_t; done

This uses find to find all files, grep to strip out the ones with a .bz2 extension and then feed them one at a time into bzip2. I expect some of the quoting is wrong, though - I'd test the bit in the backquotes separately first.

Good luck! You might want to use xz instead, though - it usually compresses better - or even tar everything up and bzip2 or xz instead.


With zsh (setopt extended_glob must be on):

bzip2 **/^*.bz2(.)

** recurses in subdirectories; ^*.bz2 matches everything except *.bz2; (.) restricts to regular files.

With bash 4, if you're ok with ignoring bzip2's complains about being invoked on directories:

bzip2 **/!(*.bz2)