Пошук та видалення дублікатів файлів в OSX за допомогою сценарію


11

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

Відкрийте термінал із прожектора або папки «Утиліти» Перейдіть до каталогу (папки), з якого потрібно шукати (включаючи підпапки) за допомогою команди cd. У командному рядку введіть cd, наприклад cd ~ / 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

По-перше, вам доведеться переупорядкувати перший командний рядок, щоб підтримувався порядок файлів, знайдених командою 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

Сподіваюся, це допомагає =)


39

Ще один варіант - використовувати fdupes:

brew install fdupes
fdupes -r .

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


7
fdupesдивовижно! Працював як шарм! Дякую брате!
racl101

3

Я написав сценарій, який перейменовує ваші файли, щоб відповідати хешу їх вмісту.

Він використовує підмножину байтів файлу, так що це швидко, і якщо відбувається зіткнення, він додає лічильник такому імені:

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

Це дозволяє легко переглядати та видаляти дублікати самостійно, не довіряючи чужому програмному забезпеченню своїми фотографіями більше, ніж потрібно.

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

введіть тут опис зображення


+1 просто для GIF-дисплея !!
NoobEditor

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

Ви також можете автоматично видаляти дублікати з видаленням дублікатів файлів, запропонованим у цій публікації .


1
(1) Що таке "EagleFiler"? Це частина macOS? Якщо ні, то де його взяти? (2) Це означає один довгий блок коду (як я його виправив)? (3) Виправте відступ. (4) Як саме це використовується?
Скотт
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.