Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I'm looking to compare directories of Drupal themes. A drupal theme is a directory composed of several files, and I'm trying to figure out which ones are essential. For instance, they might all have a file called template.php or page.tpl.php.

How can I find the set of all common files for several directories? In my case, all the 'same' files (those of the same name) are going to be in the same level directory.

share|improve this question
There are some answers in the 'Shell Puzzle' section of ukuug.org/newsletter/10.4 (though they're shell-golf-ish). – James Youngman Jun 26 '12 at 0:50
up vote 6 down vote accepted

List all names (not paths) of files common to all directories.

dirs=( "A dir" "B dir" "C dir" "D dir" )
find "${dirs[@]}" -maxdepth 1 -type f -name "*" -printf '%f\n' |
  sort | uniq -c | sed -n "s/^ *${#dirs[@]} //p"

Or call it as a script-file or function, with the directories as parameters.

find "$@" -maxdepth 1 -type f -name "*" -printf '%f\n' |
  sort | uniq -c | sed -n "s/^ *$# //p"
share|improve this answer

With Meld you can compare two directories, and see which files are present in one, and not in the other and vice versa. It can also show the differences between the common files.

share|improve this answer

For 3 directories, one of them the current, and two 'a' and 'b', you can chain the test like this:

ls a/$(ls b/$(ls *.php) 2>/dev/null) 2>/dev/null

if the files have a common pattern (like .php) and don't contain whitespace in filenames.

Using ls in Scripts is always problematic and I normally discourage from using it, but if you have an overview about all the files in the directory where the search starts, and it doesn't contain whitespace, nor special characters like "*" or "?", "<" or "|", it should be save to use it.

share|improve this answer

You can display a list of names sorted by the number of directories they appear in.

find */ |              # traverse all the template directories
sort -t / -k 2 |       # sort, ignoring the first field
tr '/' '\t' |          # turn / into tabs
uniq -f 1 -c |         # count duplicates, ignoring the first field
tr '\t' '/' |          # turn tabs back into /
sort -t / -s -k 1n     # sort by the number of occurrences
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.