Znajdowanie i usuwanie duplikatów plików w systemie OSX za pomocą skryptu

11

From: http://www.chriswrites.com/2012/02/how-to-find-and-delete-duplicate-files-in-mac-os-x/ Jak to zmienić, aby usunąć tylko pierwszą wersję plik, który widzi.

Otwórz Terminal z Spotlight lub folder Utilities Przejdź do katalogu (folderu), z którego chcesz wyszukiwać (w tym podfolderów) za pomocą polecenia cd. W wierszu polecenia wpisz cd, na przykład cd ~ / Documents, aby zmienić katalog na domowy folder Dokumenty W wierszu polecenia wpisz następujące polecenie:

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

Ta metoda wykorzystuje prostą sumę kontrolną do ustalenia, czy pliki są identyczne. Nazwy zduplikowanych elementów zostaną wymienione w pliku o nazwie duplicates.txt w bieżącym katalogu. Otwórz to, aby wyświetlić nazwy identycznych plików Istnieją teraz różne sposoby usuwania duplikatów. Aby usunąć wszystkie pliki z pliku tekstowego, w wierszu polecenia wpisz:

while read file; do rm "$file"; done < duplicates.txt
Sójka
źródło

Odpowiedzi:

4

Po pierwsze, musisz zmienić kolejność pierwszego wiersza poleceń, aby zachować kolejność plików znalezionych przez polecenie 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

(Uwaga: do celów testowych na moim komputerze użyłem find . -type f -exec cksum {} \;)

Po drugie, jednym ze sposobów drukowania wszystkich oprócz pierwszego duplikatu jest, powiedzmy, użycie pliku pomocniczego /tmp/f2.tmp. Wtedy moglibyśmy zrobić coś takiego:

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.tmpPrzed uruchomieniem upewnij się, że istnieje i jest pusty, na przykład za pomocą następujących poleceń:

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

Mam nadzieję, że to pomaga =)

Janito Vaqueiro Ferreira Filho
źródło
39

Inną opcją jest użycie fdupes:

brew install fdupes
fdupes -r .

fdupes -r .odnajduje duplikaty plików w bieżącym katalogu. Dodaj, -daby usunąć duplikaty - zostaniesz zapytany, które pliki zachować; jeśli zamiast tego dodasz -dN, fdupes zawsze zachowa pierwszy plik i usunie inne pliki.

Lri
źródło
7
fdupesjest niesamowite! Działa jak urok! Dzięki stary.!
racl101
3

Napisałem skrypt, który zmienia nazwy plików, aby pasowały do ​​skrótu ich zawartości.

Wykorzystuje podzbiór bajtów pliku, więc jest szybki, a jeśli dojdzie do kolizji, dodaje licznik do nazwy w następujący sposób:

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

Ułatwia to przeglądanie i usuwanie duplikatów we własnym zakresie, bez ufania czyjegoś oprogramowania swoim zdjęciom bardziej, niż potrzebujesz.

Skrypt: https://gist.github.com/SimplGy/75bb4fd26a12d4f16da6df1c4e506562

wprowadź opis zdjęcia tutaj

Prostota
źródło
+1 tylko za wyświetlanie GIF !!
NoobEditor
0

Odbywa się to za pomocą aplikacji EagleFiler opracowanej przez Michaela Tsai .

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

Możesz także automatycznie usunąć duplikaty za pomocą narzędzia do usuwania duplikatów plików sugerowanego w tym poście .

Dejise
źródło
1
(1) Co to jest „EagleFiler”? Czy to część systemu macOS? Jeśli nie, to skąd to masz? (2) Czy to ma być jeden długi blok kodu (sposób, w jaki to naprawiłem)? (3) Popraw wcięcie. (4) Jak dokładnie tego używa się?
Scott