I have a directory with many log files, with filenames like acct.20111001 up to acct.20111030. I want to zip them by running:

tar -cvjf acct.20111001.bz2 acct.20111001

How can I use find to compress them instead of running the tar command for each and every file?

I'm thinking something like this, but I know this command doesn't work:

find /home/log/2011/10 -name "acct.201110[0-9]" -exec tar -cvjf {}.bz2 {} \;
  • 1
    Why bother with tar if you're only putting one source file in each archive. Just....find /home/log/2011/10 -name "acct.201110[0-9]" -exec bzip2 {}; and tarring the compressed files, although slightly less efficient than compressing the archive is more robust. – symcbean Nov 22 '11 at 17:38
  • 1
    @symcbean bzip2 can be useful, but its usage does not solve the main problem here - the files are not matched properly! – rozcietrzewiacz Nov 22 '11 at 23:52

The regular expression you've used with find does not match all files in the range acct.20111001 to acct.20111030, because you forgot about the last digit. If it's OK for you to match also acct.20111000 (in case it exists, which I doubt judging from the date-look of the names), you can use

find /home/log/2011/10 -name "acct.201110[0-3][0-9]" -exec tar -cvjf {}.bz2 {} \;

Another option, especially when you have few files to operate on (less than hundreds) is not to use find, but a simple for loop instead. You can then make use of range expression that results in a list of zero-padded numbers:

 for file in acct.201110{01..30}; do tar -cvjf $file.bz2 $file; done

Yet Another option is possible if acct.20111001 through acct.20111030 are the only files that begin with acct.201110 (which, again, I suspect to be the case) - then you can just use acct.201110* with any of the above mentioned commands.


Something like

for file in acct.201110[0-9]; do tar -cvjf $file.bz2 $file; done

should work (maybe with a better glob to catch all days), but your problem sounds like logrotate or Newsyslog is what you could need.


The tool you want for this is cpio(1). This will take a list of files from stdin and produce an archive. If you need to produce an archive in tar format, use the -H tar option.

  • It is not what the OP asked for. He asked for a command to compress each file separately. – rozcietrzewiacz Nov 22 '11 at 17:00
  • If that's the case I would agree with symcbean's comment - why not just use bzip2 directly. – ConcernedOfTunbridgeWells Nov 22 '11 at 18:34
  • Yes, one can (it will remove the original files by default), but that does not show the reason why OP's command did not work. – rozcietrzewiacz Nov 22 '11 at 23:37
  • 1
    +1 since, as it turns out, it appears the user may intend to compress them all into one archive. the users intent is to save space. Also, read this: rightsock.com/~kjw/Ramblings/tar_v_cpio.html – djangofan Nov 23 '11 at 0:06

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.