Trovare e rimuovere file duplicati in osx con uno script


11

Da: http://www.chriswrites.com/2012/02/how-to-find-and-delete-duplicate-files-in-mac-os-x/ Come posso modificarlo per eliminare solo la prima versione di il file che vede.

Apri Terminale da Spotlight o dalla cartella Utilità Passa alla directory (cartella) da cui vuoi cercare (comprese le sottocartelle) usando il comando cd. Al prompt dei comandi digitare cd, ad esempio cd ~ / Documents per modificare la directory nella cartella Documenti principale. Al prompt dei comandi, digitare il comando seguente:

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

Questo metodo utilizza un semplice checksum per determinare se i file sono identici. I nomi degli elementi duplicati verranno elencati in un file denominato duplicates.txt nella directory corrente. Apri questo per visualizzare i nomi di file identici Ora ci sono vari modi per eliminare i duplicati. Per eliminare tutti i file nel file di testo, al prompt dei comandi digitare:

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

Risposte:


4

Innanzitutto, dovrai riordinare la prima riga di comando in modo da mantenere l'ordine dei file trovati dal comando 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

(Nota: a scopo di test nella mia macchina che ho usato find . -type f -exec cksum {} \;)

In secondo luogo, un modo per stampare tutto tranne il primo duplicato è usare un file ausiliario, diciamo /tmp/f2.tmp. Quindi potremmo fare qualcosa del tipo:

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

Assicurati solo che /tmp/f2.tmpesista e sia vuoto prima di eseguirlo, ad esempio attraverso i seguenti comandi:

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

Spero che questo aiuti =)


39

Un'altra opzione è usare fdupes:

brew install fdupes
fdupes -r .

fdupes -r .trova i file duplicati ricorsivamente nella directory corrente. Aggiungi -dper eliminare i duplicati: ti verrà chiesto quali file conservare; se invece aggiungi -dN, fdupes manterrà sempre il primo file ed eliminerà altri file.


7
fdupesè fantastico! Ha funzionato come un fascino! Grazie fratello!
racl101,

3

Ho scritto uno script che rinomina i tuoi file in modo che corrispondano a un hash del loro contenuto.

Utilizza un sottoinsieme dei byte del file, quindi è veloce e se c'è una collisione aggiunge un contatore al nome in questo modo:

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

Ciò semplifica la revisione e l'eliminazione dei duplicati da soli, senza fidarsi del software di qualcun altro con le tue foto più del necessario.

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

inserisci qui la descrizione dell'immagine


+1 solo per la visualizzazione GIF !!
NoobEditor,

0

Questo viene fatto con l'aiuto dell'app EagleFiler, sviluppata da Michael 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

Puoi anche eliminare automaticamente i duplicati con la rimozione dei file duplicati suggerita in questo post .


1
(1) Che cos'è "EagleFiler"? Fa parte di macOS? In caso contrario, dove lo trovi? (2) Vuol dire che è un lungo blocco di codice (il modo in cui l'ho risolto)? (3) Correggi il rientro. (4) Esattamente come si usa questo?
Scott,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.