Filenames are ones shown below, but the directory will be libgit2-0.21-1 when tar xvf v0.21.1.tar.gz, so how use one-liner to get the directory name(report error if more than two directory exist):

tar tvf v0.21.1.tar.gz | head
drwxrwxr-x root/root         0 2014-08-05 08:09 libgit2-0.21.1/
-rw-rw-r-- root/root      1169 2014-08-05 08:09 libgit2-0.21.1/.HEADER
-rw-rw-r-- root/root        22 2014-08-05 08:09 libgit2-0.21.1/.gitattributes
-rw-rw-r-- root/root       321 2014-08-05 08:09 libgit2-0.21.1/.gitignore
-rw-rw-r-- root/root      1246 2014-08-05 08:09 libgit2-0.21.1/.mailmap

I have one solution for this but obviously this is not the best one(I also have to check if there is more than one directory at the top):

mkdir libgit2 && tar xvf v0.21.1.tar.gz -C libgit2 --strip-components 1

Execute the following script with your tarball as command line parameter


DIR=$(tar tvf ${1} | egrep -o "[^ ]+/$")

if [ $(echo ${DIR} | egrep -o " " | wc -l) -eq 0 ]; then
    echo ${DIR};
    echo "ERROR: multiple directories in tarball base"
    exit 1
  • but use [[ and ]] in if statement will be precise with bash. – schemacs Oct 29 '14 at 13:46

Update Sorry forgot you also wanted the name of the top most directory. I updated the command to include an 'else'. If only one directory is found, it will echo its name. If 'ERROR is thrown, you can just view the contents of 'test.file' to see what directories are in the tar.

Try this:

$ zcat test.tar.gz | tar xvf - | \
    awk -F/ '{print $1}' | \
    uniq > test.file && \
    if (($(wc -l 'test.file' | \
    awk '{print $1}')>1));then echo "ERROR";else cat test.file;fi

man zcat

zcat is identical to gunzip -c. (On some systems, zcat may be installed as gzcat to preserve the original link to compress.) zcat uncompresses either a list of files on the command line or its standard input and writes the uncompressed data on standard output. zcat will uncompress files that have the correct magic number whether they have a .gz suffix or not.

awk -F/ '{print $1} | uniq

Print first word marked by '/' that is unique only.

> test.file

Write output to file

(($(wc -l 'test.file' | awk '{print $1}')>1))

The double ((..)) construct permits arithmetic expansion and evaluation. wc -l gets line count in file. awk '{print $1}')>1 get first column only, which is the line count number and see if that number is greater than 1. then echo "ERROR" print 'ERROR' if more than one directory found in tar file.

Hope that helps.

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.