I am trying to compare 2 directories ( A / B ) in Linux and DELETE any files from B which DO NOT exist in A.

For example, if file '1.jpg' exists in Directory B but does not exist in Directory A then it needs to be deleted from B.

I have tried using diff but all the files are essentially different so it doesn't seem to work. (They are thumbnails of different sizes but have the same id's). So, this has to be done by file name only and ignore the actual contents of the file.

Can someone please shed some light on how to do this with minimal effort?

  • A and B contain files only? Or they have subdirectories, which in turn also have files? You need recursive solution or for the one level directory? – MiniMax Jun 5 '17 at 23:11
  • There are no subdirectories. Each directory contains only files. – master00 Jun 5 '17 at 23:21

rsync can do what you want quickly and easily:

rsync --dry-run --verbose --recursive --existing --ignore-existing --delete-after A/ B/

From the help:

 --existing              skip creating new files on receiver
 --ignore-existing       skip updating files that already exist on receiver
 --delete                delete extraneous files from destination dirs

Remove the dry-run option after you're satisfied with the proposed results, to actually execute the deletions.

The man page has more explicit description of the options and even mentions your use case:

   --existing, --ignore-non-existing
      This  tells rsync to skip creating files (including directories)
      that do not exist yet on the destination.   If  this  option  is
      combined  with  the  --ignore-existing  option, no files will be
      updated (which can be useful if all you want to do is to  delete
      extraneous files).

      This  tells  rsync  to skip updating files that already exist on
      the destination (this does not ignore  existing  directores,  or
      nothing would get done).  See also --existing.
  • Doesn't rsync apply some sort of hash to each file like the diff command does? As I mentioned, the files themselves are not identical. Only the filenames are identical. – master00 Jun 5 '17 at 23:47
  • 1
    Only when it's comparing files, which is why I suggested --ignore-existing. – drewbenn Jun 5 '17 at 23:49
  • Good to know. This seemed to do the trick, thanks! – master00 Jun 5 '17 at 23:55
  • rsync is a real power tool, like lsof. Well worth the time to read the man page. – Wildcard Jun 7 '17 at 2:03

For one level directories

diff -u <(ls A) <(ls B) | sed -n '4,$s/^+//p' | xargs -I{} ls -l B/{}

ls -l should be changed to rm -v, after testing, if it is doing what you want.

rsync better, for sure. But just another variant.

Your Answer

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

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