10

От: http://www.chriswrites.com/2012/02/how-to-find-and-delete-duplicate-files-in-mac-os-x/ Как мне изменить это, чтобы удалить только первую версию файл, который он видит.

Откройте Терминал из Spotlight или папку Utilities. Перейдите в каталог (папку), в которой вы хотите искать (включая подпапки), с помощью команды cd. В командной строке введите cd, например, cd ~/Documents, чтобы изменить каталог на свою домашнюю папку Documents. В командной строке введите следующую команду:

find . -size 20 \! -type d -exec cksum {} \; | sort | tee /tmp/f.tmp | cut -f 1,2 -d ' ' | uniq -d | grep -hif – /tmp/f.tmp > duplicates.txt

Этот метод использует простую контрольную сумму, чтобы определить, идентичны ли файлы. Имена повторяющихся элементов будут перечислены в файле с именем duplicates.txt в текущем каталоге. Откройте это, чтобы просмотреть имена идентичных файлов. Теперь есть различные способы удалить дубликаты. Чтобы удалить все файлы в текстовом файле, введите в командной строке:

while read file; do rm "$file"; done < duplicates.txt

4 ответа4

27

Другой вариант - использовать fdupes:

brew install fdupes
fdupes -r .

fdupes -r . находит дубликаты файлов рекурсивно в текущем каталоге. Добавьте -d чтобы удалить дубликаты - вам будет предложено, какие файлы сохранить; если вместо того, чтобы добавить -dN fdupes всегда будет держать первый файл и удалить другие файлы.

3

Во-первых, вам нужно изменить порядок первой командной строки, чтобы сохранить порядок файлов, найденных командой find:

find . -size 20 ! -type d -exec cksum {} \; | tee /tmp/f.tmp | cut -f 1,2 -d ‘ ‘ | sort | uniq -d | grep -hif – /tmp/f.tmp > duplicates.txt

(Примечание: для тестирования на моей машине я использовал find . -type f -exec cksum {} \;)

Во-вторых, одним из способов печати всех, кроме первого дубликата, является использование вспомогательного файла, скажем, /tmp/f2.tmp . Тогда мы могли бы сделать что-то вроде:

while read line; do
    checksum=$(echo "$line" | cut -f 1,2 -d' ')
    file=$(echo "$line" | cut -f 3 -d' ')

    if grep "$checksum" /tmp/f2.tmp > /dev/null; then
        # /tmp/f2.tmp already contains the checksum
        # print the file name
        # (printf is safer than echo, when for example "$file" starts with "-")
        printf %s\\n "$file"
    else
        echo "$checksum" >> /tmp/f2.tmp
    fi
done < duplicates.txt

Просто убедитесь, что /tmp/f2.tmp существует и является пустым, прежде чем выполнять это, например, с помощью следующих команд:

rm /tmp/f2.tmp
touch /tmp/f2.tmp

Надеюсь, это поможет =)

2

Я написал скрипт, который переименовывает ваши файлы, чтобы соответствовать хэшу их содержимого.

Он использует подмножество байтов файла, поэтому это быстро, и, если есть столкновение, он добавляет счетчик к имени следующим образом:

3101ace8db9f.jpg
3101ace8db9f (1).jpg
3101ace8db9f (2).jpg

Это позволяет легко просматривать и удалять дубликаты самостоятельно, не доверяя чужим программным средствам ваши фотографии больше, чем вам нужно.

Сценарий:https://gist.github.com/SimplGy/75bb4fd26a12d4f16da6df1c4e506562

0

Это делается с помощью приложения EagleFiler, разработанного Майклом Цаем.

tell application "EagleFiler"

      set _checksums to {}
      set _recordsSeen to {}
      set _records to selected records of browser window 1
      set _trash to trash of document of browser window 1
      repeat with _record in _records
          set _checksum to _record's checksum
          set _matches to my findMatch(_checksum, _checksums, _recordsSeen)
          if _matches is {} then
              set _checksums to {_checksum} & _checksums
              set _recordsSeen to {_record} & _recordsSeen
          else
              set _otherRecord to item 1 of _matches
              if _otherRecord's modification date > _record's modification date 
then

            set _record's container to _trash
            else
                set _otherRecord's container to _trash
                set _checksums to {_checksum} & _checksums
                set _recordsSeen to {_record} & _recordsSeen
            end if
        end if
    end repeat
end tell

on findMatch(_checksum, _checksums, _recordsSeen)

    tell application "EagleFiler"
        if _checksum is "" then return {}
        if _checksums contains _checksum then
            repeat with i from 1 to length of _checksums
                if item i of _checksums is _checksum then
                    return item i of _recordsSeen
                end if
            end repeat
        end if
        return {}
    end tell

end findMatch

Вы также можете автоматически удалять дубликаты с помощью утилиты удаления дубликатов файлов, предложенной в этом посте.

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