I want to bzip2 about 1000 files. However, I am tasked to not remove the old files and leave both the original and its bz2 file in the same folder. What is the quickest way to do this.

Just to rephrase my question, suppose I have file1.txt, file2.txt, file3.txt...file1000.txt, I would need its bz2 versions in the same folder without removing them.

How to achieve this?


The -k option is described in the bzip2 manual as

-k --keep

Keep (don't delete) input files during compression or decompression.

So if you compress the files with bzip2 as ordinary, but add -k, you would not delete the original files.

To compress all .txt files in a single directory:

bzip2 -k ./*.txt

If that generates an "Argument list too long" (as it would do if you have many tens of thousands of files), use a simple shell loop instead:

for name in ./*.txt; do
    bzip2 -k "$name"
  • @kusalnanda, can I do the above by creating bzip2 files in a different directory instead of creating in the same. So basically can I give something like this bzip2 -k ./*.txt /destination – mywayz Jul 18 at 17:22
  • @mywayz bzip2 -k -c "$name" >"destdir/$name.bz2". The -c option make bzip2 write to standard output. You then redirect this to an appropriately named file in some other location. You can only do this on a single file at a time though, or you would concatenate all files into one. – Kusalananda Jul 18 at 17:29
  • Thanks Kusal, in you above comment, I do not see anywhere where the command will know which kind of file I want to BZIP in bzip2 -k -c "$name" >"destdir/$name.bz2". I am assuming I do not need to replace the first "$name" with anything? Also quotes signs remain as is right? – mywayz Jul 18 at 17:34
  • suppose I want to create bz2 of all the .txt files to a new location, so my command should look like this - bzip2 -k -c "$./*.txt" >"/mydirectory/mywayz/$name.bz2" – mywayz Jul 18 at 17:37
  • @mywayz I was using the command that you would need to insert into the loop I have show in my answer (in place of the bzip2 command that is there). As I said, you can't compress all files in one go but have to loop over each. – Kusalananda Jul 18 at 17:51

find /PATH/ -type f -execdir bzip2 -k '{}' \;

In /PATH/, recursively find all regular files, and execute in their respective directories bzip2 -k /PATH/TO/FILE which would keep the original file as well as the bzip2 compressed file.

So, a folder structure like


would result in


Above solution would run in serial, to make things faster, let's run it in parallel

find /PATH/ -type f | xargs -L1 -P10 -I{} bzip2 -k '{}'

Recursively find regular files in /PATH/ and pass them as input to xargs which then parses input in Lines (1 at a time), spawn a Process (at max 10 running at a time in parallel), use Input placeholder {} for processed input (i.e a line in this case). And execute bzip2 -k for that placeholder

Have quoted the placeholder in case, any of your filenames have whitespace in them.

  • Can you explain what this is doing before I try this. Want t make sure I don't remove any of my current file. Thanks – mywayz Jun 28 at 1:01
  • Hello GypsyCosmonaut, do I have to put anything in those curly brackets. And I and that last back slash remains as is? – mywayz Jun 28 at 1:23
  • Everything remains as is except /PATH/ of course – GypsyCosmonaut Jun 28 at 1:28
  • Thanks will try this and report back, as I am not in front of pc – mywayz Jun 28 at 1:42
  • 1
    The -L and -I options (and -n) to xargs are mutually exclusive. You are likely only getting the effect of the last one, or xargs may do something implementation-specific. – Kusalananda Jun 29 at 7:51

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.