Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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.

share|improve this question
    
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
    
FYI: GNU tar supports multi-volume tar archives with the -M parameter. –  Steve-o Sep 1 '11 at 2:49
    
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. :) –  Scytale Sep 1 '11 at 9:45
add comment

2 Answers

up vote 4 down vote accepted

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)
share|improve this answer
    
This seemed to work for me. Exact command I used was: cat *.tar.bz2 | tar -ixjv. Thanks! –  Scytale Sep 1 '11 at 9:40
add comment

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.

mountavfs
cp -p ~/.avfs$PWD/{a,b}.tgz\#/* /destination
cp -p ~/.avfs/path/to/source/*.tgz(e\''REPLY=$REPLY\#'\')/* /destination
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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