I was wondering whether (and, of course, how) it’s possible to tell tar to extract multiple files in a single run.

I’m an experienced Unix user for several years and of course I know that you can use for or find or things like that to call tar once for each archive you want to extract, but I couldn’t come up with a working command line that caused my tar to extract two .tar.gz files at once. (And no, there’s nothing wrong with for, I’m merely asking whether it’s possible to do without.)

I’m asking this question rather out of curiosity, maybe

  • there’s a strange fork of tar somewhere that supports this
  • someone knows how to use the -M parameter that tar suggested to me when I tried tar -zxv -f a.tgz -f b.tgz
  • we’re all blind and it’s totally easy to do — but I couldn’t find any hint in the web that didn’t utilize for or find or xargs or the like.

Please don’t reply with tar -zxvf *.tar.gz (because that does not work) and only reply with “doesn’t work” if you’re absolutely sure about it (and maybe have a good explanation why, too).

Edit: I was pointed to an answer to this question on Stack Overflow which says in great detail that it’s not possible without breaking current tar syntax, but I don’t think that’s true. Using tar -zxv -f a.tgz -f b.tgz or tar -zxv --all-args-are-archives *.tar.gz would break no existing syntax, imho.

  • Out of curiosity, what is the situation that caused you to start thinking about how to avoid a looping construct?
    – unclejamil
    Sep 1 '11 at 2:35
  • 1
    FYI: GNU tar supports multi-volume tar archives with the -M parameter.
    – Steve-o
    Sep 1 '11 at 2:49
  • 1
    unclejamil: I’m writing a HowTo and one of the steps in it involves unpacking several compressed files (.tar.bz2, .tar.gz, .zip). And since it’s a HowTo, I was wondering what the most elegant command line to do that would be. :)
    – scy
    Sep 1 '11 at 9:45

This is possible, the syntax is pretty easy:

$ cat *.tar | tar -xvf - -i

The -i option ignores the EOF at the end of the tar archives, from the man page:

-i, --ignore-zeros
ignore blocks of zeros in archive (normally mean EOF)
  • 3
    This seemed to work for me. Exact command I used was: cat *.tar.bz2 | tar -ixjv. Thanks!
    – scy
    Sep 1 '11 at 9:40
  • 2
    <For tgz> cat *.tgz | tar -xzvf - -i -C /destination/ <or> for file in *.tgz; do tar -xzvf $file -C /destination/; done
    – Ferroao
    Dec 6 '17 at 13:18
  • @polynomial: is there any reason, why we cant use ls instead of cat? wouldnt that work as well?
    – Rika
    Feb 2 '20 at 3:55
  • 1
    @Rika, tar -f - reads from stdin, hence one needs to pipe the content of the archives, not their names. That's why ls wouldn't work.
    – Daniel Le
    Dec 29 '20 at 8:44
  • @DanielLe Thanks a lot really appreciate it
    – Rika
    Dec 29 '20 at 9:23

For *.tar.gz:

for file in *.tar.gz; do tar -zxf "$file"; done

For *.tar.bz2:

for file in *.tar.bz2; do tar -jxf "$file"; done

For *.tar.xz:

for file in *.tar.xz; do tar -Jxf "$file"; done
  • 1
    Fix the formatting here, and this will be more readable.
    – eyoung100
    Mar 4 '15 at 17:51
  • this is great. the format is also great because thats how it looks in the terminal Apr 10 '15 at 11:31
  • 1
    Don't forget to put quotes around $file if your files have names with spaces. Dec 1 '16 at 13:22
  • This does not really answer the question of whether it's possible to extract multiple archives using a single invocation of tar. Furthermore, the user says they are already familiar with how to use for-loops to iterate over a set of files.
    – Kusalananda
    May 21 '18 at 12:35

You need to use a loop. It wouldn't break the tar command line syntax to allow multiple -f options, but it would require adding code to process several archives in sequence, with all kinds of edge conditions (What happens if an archive in the middle is malformed? Can the archives use different compression mechanisms? Can you have multiple -C options (GNU tar option to extract to a particular directory), too? What about -K (GNU tar option to start at a certain member name)? …).

One possibility avoiding a for loop is to install and activate AVFS, a FUSE filesystem that provides transparent access to archives. Each archive /path/to/archive doubles as a directory ~/.avfs/path/to/archive#. If you want to match the archives with wildcards, there's a hurdle of adding that # to a wildcard match; it can be done in zsh.

cp -p ~/.avfs$PWD/{a,b}.tgz\#/* /destination
cp -p ~/.avfs/path/to/source/*.tgz(e\''REPLY=$REPLY\#'\')/* /destination

find . -name "*.tar.gz" -exec tar xzf {} \;

  • what does this do? May 21 '18 at 12:24
  • 1
    This introduces an implicit loop calling tar once for each found file, and the user says they already know how to do this.
    – Kusalananda
    May 21 '18 at 12:25
  • sorry didn't read the question carefully, I was just searching the way to extract multiple tar pack, read the answer above and think use the find will be more easy.
    – zjengjie
    May 22 '18 at 6:01

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.