Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

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
add comment

3 Answers

up vote 5 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##*/}"
done

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 http://mywiki.wooledge.org/BashFAQ/100 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
add comment

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
3  
This should be the accepted answer. –  sudowned Oct 28 '12 at 3:17
add comment

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
add comment

Your Answer

 
discard

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.