How to run the file command recursively
Solution 1
The other answer provides not the best way:
find . -type f | file -f -
There are at least two problems:
-
-f
option is not required by POSIX, some implementations offile
may not support it. -
find
prints each path with a trailing newline character, so it's usually one path (file) per line. Thenfile -f -
expects one path per line. The problem is with paths that contain newlines; they are still valid in Unix (yet uncommon). In the above approach such path will get tofile
in two or more lines and the tool will treat each line as a separate path to examine.
A robust and portable way:
find . -type f -exec file -- {} +
Notes:
-
-exec file {} \;
would also work, but then a separatefile
would be invoked for every file found. With+
file
can get multiple operands (find
is still able to callfile
multiple times if there are too many files to build a single command). Expect+
to perform better. On the other handfile
that processes multiple arguments may columnize its output, so it looks "better". Therefore the two versions (with+
and with;
) may differ in formatting their outputs. - I used a double dash in case there's a file with name beginning with
-
that could be interpreted as an option. If the starting path is.
(like in this case) many implementations offind
will print paths starting with.
, so--
is not necessary; but apparently not all implementations do this.
Solution 2
The words "all the files in a given directory and its subdirectories" should lean you toward the find command:
find . -type f | file -f -
Will recursively read all files from the current directory and sub directories and have file identify their type. You might want to add -z for types that include compression.
Related videos on Youtube
Hashim Aziz
Updated on September 18, 2022Comments
-
Hashim Aziz over 1 year
I'm trying to get information about the types of all the files in a given directory tree. Running
file
in the current directory works well enough, but it doesn't traverse into sub-directories, and there doesn't seem to an option to make it do so, which seems odd for a UNIX tool.How exactly do I execute the
file
command recursively, so that it lists the file types of all the files in a given directory and its subdirectories? -
Hashim Aziz over 4 yearsI suspected that, I was kinda just hoping there was an option to
file
that I was glossing over. It seems odd to create a tool advanced enough that it can uncompress archives to search but yet not provide a single option for recursive operation, and it's not what I've come to expect of UNIX-like tools. -
Hashim Aziz over 4 yearsAlso, is piping to file superior to using
-exec
? -
davolfman over 4 yearsYes, very. This version calls file once, exec calls it for every line, or every N lines. The forks and execs add up massively on a large operation.
-
davolfman over 4 yearsAlso, the old Unix philosophy is "A set of small sharp tools". Combining tools to perform a job is part of that, so tools are built to be combined. For example putting human-output on stderr so the useful output piped form stdout is easier to work with by the next tool in line. More recent GNU and Linux stuff may not follow that exactly.