I got a problem on untar a list of .tar.gz file in a directory.
In my directory,
there are lots of result.tar.gz , they are the same name, they are renamed as...
result.tar.gz
result (1).tar.gz
result (2).tar.gz
result (3).tar.gz
result (4).tar.gz
....
....
....
....
I want to untar all of them in one linux command. so I try to use
tar zxvf *
or
tar zxvf result*.tar.gz
both got this error
tar: result (3).tar.gz: Not found in archive
tar: result (4).tar.gz: Not found in archive
tar: result (5).tar.gz: Not found in archive
tar: result (6).tar.gz: Not found in archive
Who knows how to untar all of the packages at the same time?
tar
only knows how to process one .tar file at a time: the one specified with f
. If you specify additional names on the command line they are interpreted as files to extract from the specified .tar file.
Most of the answers so far do not account for unusual file names e.g., those containing spaces, newlines or other special characters).
The correct answer is this:
for file in *.tar.gz ; do
tar xzf "$file"
fi
The other acceptable answer would be to use find
find . -maxdepth 1 -type f -name '*.tar.gz' -exec tar xzf {} \;`
Why can't I...
Use ls *.tar.gz | ...
?
Because ls
will clobber certain characters in file names (ie, it is not safe). If you must use ls
for this you should be careful to use ls -1
and then be careful that you treat newline and only newline as a record seperator. This is still not safe, but it's safer.
Use $file
without the quotes?
Because a file with spaces in the name, among other things, will be interpreted in ways you do not expect. Example: A file named monthly backup.tar.gz
will be interpreted as tar xzf monthly backup.tar.gz
and you will get an error because the archive monthly
does not exist.
Use echo | xargs tar
?
Because echo
will mangle file names, specifically ones with spaces in the name.
When performing a while read
loop you almost always want to use read -r
, which will prevent backslashes in the input from being interpreted as escape sequences. If you had a file named foo\bar
then read
without -r
would not read it correctly.
EDIT:
Per comments, here's a method for extracting tarballs into subdirectories.
for file in *.tar.gz ; do
# strip any leading path information from the file name
name_only="${file##*/}"
# strip the extension .tar.gz
without_extension="${name_only%.tar.gz}"
# make a directory named after the tar file, minus extension
mkdir -p "$without_extension"
# extract the file into its own directory
tar xzf "$file" -C "$without_extension"
done
Above I extract into directories named after the tarball. However, any scheme for making unique directory names would be sufficient. For example, here's a version that extracts to sequentially numbered directories:
let n=0
for file in *.tar.gz ; do
mkdir -p "$n";
tar xzf "$file" -C "$n"
let n=n+1
done
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With