I'm looking to do something that I'm sure is pretty straightforward - hopefully with a Terminal command similar to this: How can I compare and delete duplicate files between multiple folders on El Capitan?.

I've been keeping photos in a number of directories, in one of two formats:

Short Trips:

  • /Users/Ben/Pictures/Location/pic1.jpg

Long Trips:

  • /Users/Ben/Pictures/Trip Name/Location1/pic1.jpg

  • /Users/Ben/Pictures/Trip Name/Location2/pic1.jpg

Most of these folders contain a subfolder called 'Best', where I have copied my favourite photos from the parent folder, thereby duplicating each photo.


Short Trips:

  • /Users/Ben/Pictures/Location/Best

Long Trips:

  • /Users/Ben/Pictures/Trip Name/Location1/Best

  • /Users/Ben/Pictures/Trip Name/Location2/Best

N.B. Some of the smaller albums don't contain this 'Best' folder.

What I want to do is to scan recursively through each folder looking for a 'Best' folder. If it is found, then I want to go through each of the files within this folder and delete the corresponding item from the parent folder.

e.g. Parent folder contains:

  • /Users/Ben/Pictures/Location1/pic1.jpg
  • /Users/Ben/Pictures/Location1/pic2.jpg
  • /Users/Ben/Pictures/Location1/pic3.jpg

and the 'Best' folder contains

  • /Users/Ben/Pictures/Location1/Best/pic1.jpg
  • /Users/Ben/Pictures/Location1/Best/pic3.jpg

Then I want to delete pic1 and pic3 from the parent folder and only keep pic2.

Thanks for any help.

  • 1
    Your folder design could be improved: you would have been better to have created links instead of copies in Best/, which would have used negligible space, but kept all the originals together for each location. Your question is wrong: when you give ~/ as the prefix to the folder contents, I presume you mean ./, otherwise the folders would be identical. Furthermore, I find it difficult to work out from your question where the Best/ folders reside. Please update your question to clarify these issues. – AFH Jun 23 '17 at 20:01
  • Thanks, I've updated the main post as per your request. Hopefully it's clear now. I appreciate the structure isn't good in hindsight. I'd happily look at replacing the duplicates with symlinks too if that makes it easier. – benje Jun 23 '17 at 20:13
  • To correctly list those paths, they should all start ~/Pictures/ which implies /Volumes/[MacHD]/Users/[UserName]/ without having to know the actual name of either the hard drive or user. – Tetsujin Jun 24 '17 at 10:38

Now that you have clarified your question, I think I can see what you need:-

find /Users/Ben/Pictures/ -type d -name Best | \
     while read -r d; \
     do for f in "$d"/*; \
        do cmp "$f" "${f%/Best/*}/${f##*/Best/}" && \
           ln -sf "${f%/Best/*}/${f##*/Best/}" "$f"; \
        done; \

This works as follows:-

  • Use find to locate all the Best/ subdirectories.
  • For each subdirectory found, compare each of its files with the original in the parent folder.
  • If they are identical, overwrite the file in Best/ with a link to the file in the parent folder.
  • If you prefer hard to symbolic links you can use ln -f ... instead of ln -sf ... (either will suit your purposes).
  • The key parse elements are ${f%/Best/*}, which removes /Best/FileName from the end of the path (should be the same as $d), and ${f##*/Best/}, which isolates the file name from the path (should be the same as ${f##*/}).
  • I don't usually write complete scripts as answers, but I can't see any easy way to guide you through the writing of it; make sure you understand it before you use it - add echo in front of the critical ln command to make sure it will do what you expect.

I have tested this on Ubuntu, but OS/X implementations of cmp and ln should work with the same parameters.

Just in case you get get things wrong, back up the directories before you start.


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.