Velvet Star Monitor

Standout celebrity highlights with iconic style.

updates

How to run the file command recursively

Writer Matthew Harrington

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?

2 Answers

The other answer provides not the best way:

find . -type f | file -f -

There are at least two problems:

  1. -f option is not required by POSIX, some implementations of file may not support it.
  2. find prints each path with a trailing newline character, so it's usually one path (file) per line. Then file -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 to file 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 separate file would be invoked for every file found. With + file can get multiple operands (find is still able to call file multiple times if there are too many files to build a single command). Expect + to perform better. On the other hand file 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 of find will print paths starting with ., so -- is not necessary; but apparently not all implementations do this.

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.

4

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy