Я пытаюсь сделать что-то, что, я уверен, довольно просто - надеюсь, с помощью команды Terminal, похожей на эту: Как я могу сравнить и удалить дубликаты файлов в нескольких папках на El Capitan? ,

Я храню фотографии в нескольких каталогах в одном из двух форматов:

Короткие поездки:

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

Длинные поездки:

  • / Пользователи / Бен / Фотографии / Название поездки / Местоположение1 / pic1.jpg

  • / Пользователи / Бен / Картинки / Название поездки / Местоположение2 / pic1.jpg

Большинство из этих папок содержат подпапку «Лучшая», куда я скопировал свои любимые фотографии из родительской папки, таким образом дублируя каждую фотографию.

например

Короткие поездки:

  • /Users/Ben/ Фотографии / Местонахождение / Best

Длинные поездки:

  • / Пользователи / Ben / Картинки / Название поездки / Location1 / Best

  • / Пользователи / Ben / Картинки / Название поездки / Location2 / Best

NB. Некоторые из небольших альбомов не содержат эту папку «Best».

Я хочу рекурсивно сканировать каждую папку в поисках «Лучшей» папки. Если он найден, я хочу просмотреть все файлы в этой папке и удалить соответствующий элемент из родительской папки.

например, родительская папка содержит:

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

и папка «Best» содержит

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

Затем я хочу удалить pic1 и pic3 из родительской папки и оставить только pic2.

Спасибо за любую помощь.

1 ответ1

0

Теперь, когда вы прояснили свой вопрос, я думаю, что вижу, что вам нужно:

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; \
     done

Это работает следующим образом:

  • Используйте find чтобы найти все Best/ подкаталоги.
  • Для каждого найденного подкаталога сравните каждый из его файлов с оригиналом в родительской папке.
  • Если они идентичны, перезапишите файл в Best/ со ссылкой на файл в родительской папке.
  • Если вы предпочитаете жесткие символические ссылки, вы можете использовать ln -f ... вместо ln -sf ... (любой из них подойдет для ваших целей).
  • Ключевыми элементами синтаксического анализа являются ${f%/Best/*} , который удаляет /Best/FileName с конца пути (должен совпадать с $d), и ${f##*/Best/} , который изолирует имя файла из пути (должно совпадать с ${f##*/}).
  • Я обычно не пишу полные сценарии в качестве ответов, но я не вижу простого способа, чтобы помочь вам в его написании; убедитесь, что вы понимаете это, прежде чем использовать его - добавьте echo перед критической командой ln чтобы убедиться, что она будет делать то, что вы ожидаете.

Я проверил это на Ubuntu, но реализации cmp и ln OS/X должны работать с одинаковыми параметрами.

Если у вас что-то не так, сделайте резервную копию каталогов, прежде чем начать.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .