1

I have many files in a directory. every one of them have very different name:

one.tar.gz
juk.tar.gz
cv.tar.gz
erf.tar.gz
vcx.tar.gz
cxcd.tar.gz
vc.tar.gz
jkjk.tar.gz
zxc.tar.gz
asd.tar.gz
ghj.tar.gz
kll.tar.gz
qwe.tar.gz

Extracting one by one is very time consuming. So I want to extract all of that files using one command. I've tried tar -xzf * but not works

0

7 Answers 7

10

Using find mojo:

find . -maxdepth 1 -type f -iname '*.tar.gz' -exec tar xzf '{}' \;
2
  • very handy one-liner! :)
    – skazhy
    Commented Jan 18, 2011 at 12:51
  • 2
    I would want to include -maxdepth 1 to avoid accidental expansion of tarballs in subdirectories.
    – phogg
    Commented Jan 18, 2011 at 16:53
7

It's expected not to work as tar -xzf *.tar.gz will expand in your case to tar -xzf one.tar.gz juk.tar.gz cv.tar.gz ... Which means gunzip one.tar.gz and extract from it the files named juk.tar.gz, cv.tar.gz, etc. This is clearly not what you want.

You have to do a loop on all tar.gz files to extract them.

For instance:

for f in *.tar.gz ; do tar -xzf $f ; done
0
1
for i in *.tar.gz
do tar -xzf $i
done

Will work fine

1

One way's to use a for loop.

for i *.tar.gz; do tar -xvz $i; done
1
ls *.tar.gz | xargs -n 1 tar -xzf
3
  • -1 for piping the output of ls
    – phogg
    Commented Jan 18, 2011 at 16:47
  • I think this was downmodded because if a filename has a space in it, xargs will pass it as two (or more) chunks to tar. But most of the for loops so far on this page don't deal with this problem either. Meh. Commented Jan 18, 2011 at 17:20
  • Other for loops on this page break on spaces and special characters, so I did not vote them up. Their form was correct with simply a small omission. This one breaks that way, too, but does it in a more egregious manner. The output of ls is for human consumption only unless you use -1 or similar, but even then I would avoid it. See ParsingLS.
    – phogg
    Commented Jan 18, 2011 at 18:28
1

goreSplatter's is what I would do, but meanwhile here's the correct form of the for loop version:

for tarball in *.tar.gz ; do
    tar xzf "$tarball"
done
  • It's important to quote the expansion of the variable in case some files have spaces or other special characters in their names.
  • Bundled arguments do not require and should not use a leading switch (-) character, for portability.
  • Modern tars will even allow you to omit the z since it autodetects compression type.
2
  • Don't #2 "do not use leading dash for portability" and #3 "compression auto-detected by modern tar versions?" sort of contradict each other? Commented Jan 19, 2011 at 13:45
  • I did not omit the z in my example for this reason. There's another reason not to use a leading switch which feeds in to the reason you might omit the z: One less character to type.
    – phogg
    Commented Jan 20, 2011 at 11:13
1

Another solutions could be :

cat *.tar.gz | tar xvf - -ignore-blocks

But it's a bug from the tar parser (according to 1) So it's better to use :

cat *.tar.gz | tar xvf - --ignore-zeros --listed-incremental=noreblocks

Or directly (the one I use) :

cat *.tar.gz | tar tvf - --ignore-zeros

Exemple : [a-c].tar files are the same.

me@herpes:/tmp/test$ ls -1
aa.tar
a.tar
bb.tar
b.tar
cc.tar
c.tar
me@herpes:/tmp/test$ cat * | tar tf - --ignore-zeros
a1
a2
stopbroker
startbroker
b1
b2
stopbroker
startbroker
c1
c2
stopbroker
startbroker
me@herpes:/tmp/test$ for i in *; do tar tf $i;done
a1
a2
stopbroker
startbroker
b1
b2
stopbroker
startbroker
c1
c2
stopbroker
startbroker

You must log in to answer this question.