I have multiple .tar.gz and .zip files and I wanted to know the file types of files inside these files without extracting them. How can I achieve this. I can list the files of .tar.gz using the command tar -tzf 'filename' and unzip -l 'filename' . I could not find a way to identify the file types inside these files. How can I achive this? I am using centos 6.6

Output of command tar -tzf 'test.tar.gz'

-rw-r--r-- root/root     89403 2019-05-26 11:31 abc.tar.gz
-rw------- root/root      2842 2019-05-26 09:41 anaconda-ks.cfg
-rw-r--r-- root/root      8823 2019-05-26 09:41 install.log
-rw-r--r-- root/root      3314 2019-05-26 09:40 install.log.syslog
-rw-r--r-- root/root    122880 2019-05-26 11:28 tin.tar
-rw-r--r-- root/root     25543 2019-05-26 11:20 tito.zip
-rw-r--r-- root/root     25487 2019-05-27 07:48 tito.ZIP

output of unzip -l test.zip

 Length      Date    Time    Name
---------  ---------- -----   ----
    89403  05-26-2019 11:31   abc.tar.gz
     2842  05-26-2019 09:41   anaconda-ks.cfg
     8823  05-26-2019 09:41   install.log
     3314  05-26-2019 09:40   install.log.syslog
   122880  05-26-2019 11:28   tin.tar
    25543  05-26-2019 11:20   tito.zip
    25487  05-27-2019 07:48   tito.ZIP
---------                     -------
   278292                     7 files
  • Commands like file determine the file "type" usually by examining the first few bytes of it, so you need to extract them depending on how you mean to infer the filetype. – muru May 28 at 6:36

With GNU tar:

tar --to-command='exec file -b -' -xvvf file.tar.gz

For zip files, you could convert to tar on the fly using bsdtar and use GNU tar again to call file on each member:

bsdtar cf - @file.zip | tar --to-command='exec file -b -' -xvvf -

It gives an output like:

-rw-rw-r-- 0/0            7653 1999-12-30 10:26 WINOBJ.HLP
MS Windows 3.1 help, Thu Dec 30 15:26:17 1999, 7653 bytes
-rw-rw-r-- 0/0            7005 2006-07-28 08:32 Eula.txt
Non-ISO extended-ASCII text, with very long lines, with CRLF line terminators
-rw-rw-r-- 0/0          729464 2011-02-14 11:37 Winobj.exe
PE32 executable (GUI) Intel 80386, for MS Windows

The file command guesses the type of a file using heuristics based on the first few bytes of the file. So, in any case the data needs to be extracted from the file. Even to report the tar tvf output, tar needs to read and uncompress the full archive as the information is stored before the content of each archive member, but none of those solutions above extract the members to disk, the data is passed from bsdtar to tar and from tar to file via pipes, the content of the archive members is not even stored as a whole in memory.

After file returns after having read the first few bytes of the file, GNU tar handles it smartly and skips the rest of the archive member (instead of dying of a SIGPIPE) before running the next file command for the next archive member.

Where it's not optimal from an efficiency point of view is that it runs one sh (to interpret the exec file -b - command line) and one file command for each regular file archive member. We use exec so that the same process is reused for sh and file (for those sh implementations like dash that don't do that optimisation by themselves).


The file command should tell you about the file itself:

$ file test.zip
test.zip: Zip archive data, at least v1.0 to extract
$ file test.tar.gz
test.tar.gz: gzip compressed data, last modified: Sun May 26 11:28:34 2019, from Uniz

But for the files inside the archives, you'd need to extract them and run file on each one individually.

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.