Ask Ubuntu is a question and answer site for Ubuntu users and developers. 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 am trying to find diffs between all files of same names across two copies of a directory (say a working and a backup). For example, I can diff two files of same name in both:

> diff d1/f.cpp d2/f.cpp

or I can find differences across the directories:

> diff d1 d2

but how can I find differences between the *.cpp files only?

> diff d1/*.cpp d2/*.cpp

does not seem to work (for obvious reasons).

[It is probably easy to solve with loops, but I am trying to find a more elegant way]

share|improve this question
up vote 8 down vote accepted

You can use a shell loop that runs diff for each file, though this will not catch the cases where d2 contains a file, but d1 doesn't. It might be sufficient though.

for file in d1/*.cpp; do
    diff "$file" "d2/${file##*/}"

Or all on one line:

for file in d1/*.cpp; do diff "$file" "d2/${file##*/}"; done

The ${file##*/} part is a special parameter expansion.

If the file variable contains d1/hello.cpp, then "${file##*/}" will expand to hello.cpp (the value of file, but with everything up to, and including, the last / removed).

So "d2/${file##*/}" will result in d2/hello.cpp and the resulting diff command is thus diff d1/hello.cpp d2/hello.cpp

See for more on string manipulations in bash.

On a side note, a version control system (such as subversion, git, mercurial etc...) would make this type of diffing much easier.

share|improve this answer
I think that of the two great answers, this on is more straight forward when there are multiple file types (although I mentioned in the question that I'm looking for a no-loops solution), so I accepted it. The one addition added is echo "${file##*/}"; before the diff command, so one knows what files are actually being compared. Also, as mentioned in @Rinzwind's answer, this method does not cover the case were the file list is not exactly the same in both directories. – ysap Dec 23 '12 at 5:00

diff -qr {DIR1} {DIR2} does all files in both directories.

  • q shows only differences
  • r does recursive. Leave it out if you do not need that

You can not tell diff directly to use wildcards but you can add:

-x PAT  --exclude=PAT
    Exclude files that match PAT.

-X FILE    --exclude-from=FILE
   Exclude files that match any pattern in FILE.

to exclude files. So if you only want *.cpp the easiest method is to create a textfile that holds all the files that are not *.cpp.

share|improve this answer
This should be the accepted answer. – sudowned Oct 28 '12 at 3:17

Some time after asking the question, I found out the meld diff utility, and am using it since then. This is a great piece of GUI based program that makes comparison and merge between files and directory a very easy task. It does two- or three-way compares.

Specifically, it answers my original question in that it shows you a color-coded comparison of the directory contents, and lets you compare specific files by a double-click on the file name.

If one needs more than a three-way comparison, then gvimdiff (based on the vim editor) is a great too as well that provides this functionality.

share|improve this answer

There's a lightweight solution for that:

  1. Set up this tiny plugin
  2. Do diff dir1 dir2 | vim -R - at shell

It will add folds and side-by-side comparison for changed files.

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.