Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I need to diff two directories:

 A: /path1/
 B: /path2/
  1. The directory A contains all files and subdirectories that are also contained in B.
  2. The files in A (and in its subdirectories) can have different contents of the equivalent files in B.
  3. The directory A (and its subdirectories) also has extra files that do not exist in B.

What I would like to achieve is:

  • Keep only the files in A that differ from the files in B plus all the extra files that don't exist in B.
  • Delete all the other files in A that do not respect the previous rule.
share|improve this question

1 Answer 1

up vote 4 down vote accepted

This approach should work:

cd /path1

find . -type f -exec cmp -s {} /path2/{} \; -delete

How it works:

  • find . -type f goes through all files in the current directory (A) and its subdirectories.

  • cmp -s {} /path2/{} silently (-s) compares the currently processed file ({}) to the matching file in B (/path2/{}).

  • If the files are identical, cmp returns true and the -exec condition matches.

  • If the -exec condition matches, -delete deletes the file.

I suggest replacing -delete with -print before running the actual command to verify if it works as expected.


To deal with leftover empty directories, you can execute the command:

find . -type d -exec rmdir -p {} \; 2> /dev/null
  • -type d only finds directories.

  • -exec rmdir -p {} \; executes rmdir -p {} for every directory that has been found.

    {} is the directory that has been found, and the -p switch makes rmdir remove its empty parent directories as well.

  • 2> /dev/null suppresses the error messages that will arise from trying to delete non-empty or previously deleted directories.

Since rmdir cannot delete non-empty directories, this should be the safest way.

share|improve this answer
    
I forgot to mention that I am on Mac Os X and I've just found out that many find options are different or are not implemented at all. I'll try to translate your command for the Mac implementation of find. Any tip would be welcome as well. –  Leonardo Mar 5 '13 at 21:07
    
According to find(1) OS X Manual Page, neither -exec nor -delete are GNU extensions. I don't have OS X (so I can't test it), but my find command should work out of the box. –  sudo Mar 5 '13 at 21:15
    
I solved installing the GNU find through brew: brew install findutils. It will create a bin called gfind that can be called instead of find or it can be aliased as find. Your script leaves the empty folders in place tough, any way to delete them? Thanks –  Leonardo Mar 6 '13 at 0:27
1  
I still don't know why it won't work with Mac OS X's find, but GNU find is much more powerful, so you haven't installed it in vain. I've edited my answer to add a solution for the empty directories. The approach assumes that rmdir cannot delete non-empty directories. As far as I know, that's true on Mac OS X a well. –  sudo Mar 6 '13 at 0:46
    
I finally found out what the problem was. GNU find automatically processes the current directory (.) if none is specified. BSD find doesn't do this, so you have to execute find . -type f .... –  sudo Mar 29 '13 at 17:02

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.