Come rimuovere i file duplicati usando bash


10

Ho una cartella con file duplicati (da md5sum( md5su un Mac)) e voglio avere un processo pianificato per rimuovere qualsiasi trovato.

Tuttavia, sono bloccato su come farlo. Quello che ho finora:

md5 -r * | sort

Che produce qualcosa del genere:

04c5d52b7acdfbecd5f3bdd8a39bf8fb gordondam_en-au11915031300_1366x768.jpg
1e88c6899920d2c192897c886e764fc2 fortbourtange_zh-cn9788197909_1366x768.jpg
266ea304b15bf4a5650f95cf385b16de nebraskasupercell_fr-fr11286079811_1366x768.jpg
324735b755c40d332213899fa545c463 grossescheidegg_en-us10868142387_1366x768.jpg
3993028fcea692328e097de50b26f540 Soyuz Spacecraft Rolled Out For Launch of One Year Crew.png
677bcd6006a305f4601bfb27699403b0 lechaustria_zh-cn7190263094_1366x768.jpg
80d03451b88ec29bff7d48f292a25ce6 ontariosunrise_en-ca10284703762_1366x768.jpg
b6d9d24531bc62d2a26244d24624c4b1 manateeday_row10617199289_1366x768.jpg
ca1486dbdb31ef6af83e5a40809ec561 Grueling Coursework.jpg
cdf26393577ac2a61b6ce85d22daed24 Star trails over Mauna Kea.jpg
dc3ad6658d8f8155c74054991910f39c smoocave_en-au10358472670_1366x768.jpg
dc3ad6658d8f8155c74054991910f39c smoocave_en-au10358472670_1366x7682.jpg

Come posso elaborare in base all'MD5 del file per rimuovere i duplicati? Non mi interessa davvero quale "originale" tengo, ma ne voglio solo uno.

Dovrei affrontarlo in modo diverso?


3
C'è già un fdupescomando che lo farà ... Non sono sicuro di quale distro si trovi, ma si trova in un pacchetto Debian con lo stesso nome. Inoltre, MD5 è un hash abbastanza debole al giorno d'oggi; probabilmente vuoi usare sha256sum o meglio sha512sum(che in realtà dovrebbe essere più veloce sul normale hardware per PC)
derobert

1
@derobert - So che MD5 è un hash debole, ma è abbastanza semplice e buono per confrontare file di piccole dimensioni :)
Warren,

bene, le collisioni MD5 sono conosciute e generabili con quantità abbastanza modeste di potenza della CPU, e c'è un comando che puoi sostituire per usare invece SHA-512, quindi ...
derobert

@derobert - Capisco che ci sono potenziali aspetti negativi nell'uso di md5 .. ma è più che adeguato in questo scenario (voler assicurarsi di non avere file duplicati in una determinata directory)
warren,

1
Giusto. Il punto principale del commento era sottolineare fdupes.
derobert,

Risposte:


3

Sto lavorando su Linux, il che significa che è il comando md5sumche genera:

> md5sum *
d41d8cd98f00b204e9800998ecf8427e  file_1
d41d8cd98f00b204e9800998ecf8427e  file_10
d41d8cd98f00b204e9800998ecf8427e  file_2
d41d8cd98f00b204e9800998ecf8427e  file_3
d41d8cd98f00b204e9800998ecf8427e  file_4
d41d8cd98f00b204e9800998ecf8427e  file_5
d41d8cd98f00b204e9800998ecf8427e  file_6
d41d8cd98f00b204e9800998ecf8427e  file_7
d41d8cd98f00b204e9800998ecf8427e  file_8
d41d8cd98f00b204e9800998ecf8427e  file_9
b026324c6904b2a9cb4b88d6d61c81d1  other_file_1
31d30eea8d0968d6458e0ad0027c9f80  other_file_10
26ab0db90d72e28ad0ba1e22ee510510  other_file_2
6d7fce9fee471194aa8b5b6e47267f03  other_file_3
48a24b70a0b376535542b996af517398  other_file_4
1dcca23355272056f04fe8bf20edfce0  other_file_5
9ae0ea9e3c9c6e1b9b6252c8395efdc1  other_file_6
84bc3da1b3e33a18e8d5e1bdd7a18d7a  other_file_7
c30f7472766d25af1dc80b3ffc9a58c7  other_file_8
7c5aba41f53293b712fd86d08ed5b36e  other_file_9

Ora usando awke xargsil comando sarebbe:

md5sum * | \
sort | \
awk 'BEGIN{lasthash = ""} $1 == lasthash {print $2} {lasthash = $1}' | \
xargs rm

La awkparte viene inizializzata lasthashcon la stringa vuota, che non corrisponderà ad alcun hash, quindi controlla per ogni riga se l'hash in lasthashè uguale all'hash (prima colonna) del file corrente (seconda colonna). Se lo è, lo stampa. Alla fine di ogni passaggio verrà impostato lasthashl'hash del file corrente (è possibile limitare l'impostazione da impostare solo se gli hash sono diversi, ma ciò dovrebbe essere una cosa minore soprattutto se non si hanno molti file corrispondenti). I nomi awk spiedi fuori vengono alimentati rmcon xargs, che chiama sostanzialmente rmcon ciò che la awkparte ci dà.

Probabilmente dovrai prima filtrare le directory md5sum *.

Modificare:

Usando il metodo Marcins puoi anche usare questo:

comm -1 -2 \
  <(ls) | \
  <(md5sum * | \
    sort -k1 | \
    uniq -w 32 | \
    awk '{print $2}' | \
    sort) \
xargs rm

Questo sottrae dalla lista lsfile ottenuta dal primo nome file di ogni hash unico ottenuto da md5sum * | sort -k1 | uniq -w 32 | awk '{print $2}'.


1
grazie: md5 -r * | sort -t ' ' -k 4 -r | awk 'BEGIN{lasthash = ""} $1 == lasthash {print $2} {lasthash = $1}' | xargs rmè la chiamata su OS X (per il suggerimento di @ Stephen Kitt , ho messo un echo 'will remove 'fine prima di provarlo con rm)
warren

Probabilmente dovresti modificare la tua domanda perché la soluzione fornita non corrisponde all'esempio di output che hai fornito.
Stephen Kitt,

1
E dovresti cambiare sort -t ' ' -k 4 -rin sort.
Tristan Storch,

@TristanStorch - buon posto :)
warren il

Ciò presuppone che non ci siano spazi nei nomi dei file, un presupposto pericoloso in ogni circostanza. (E soprattutto dato che l'OP sta usando un Mac. Ti sfido a trovare un Mac, qualsiasi Mac, che non abbia alcun nome di file contenente spazio.) :)
Wildcard,

7

È possibile identificare i file duplicati utilizzando il seguente comando:

md5sum * | sort -k1 | uniq -w 32 -d

1
Ciò genera un solo file per ogni serie di duplicati. Se vuoi eliminare tutti i duplicati e conservarne solo uno, puoi conservare quelli che ottieni con questo comando ed eliminare il resto
golimar

2

Ho incontrato fdupes come risposta a questa domanda simile: /superuser/386199/how-to-remove-duplicated-files-in-a-directory

Sono stato in grado di farlo apt-get install fdupessu Ubuntu. Avrai sicuramente voglia di leggere la pagina man. Nel mio caso, sono stato in grado di ottenere i risultati desiderati in questo modo:

fdupes -qdN -r /ops/backup/

Il che dice "guarda ricorsivamente in / ops / backup e trova tutti i file duplicati: mantieni la prima copia di ogni dato file e rimuovi silenziosamente il resto". Ciò semplifica la conservazione di numerosi dump di un database di scrittura non frequente.


1

Se hai fretta (o hai molti file) e vuoi evitare l'overhead di una specie (ci vuole tempo) ma non preoccuparti dell'overhead di memoria di una tabella hash (o hai un sacco di RAM con i tuoi lotti di file),

find . -type f -print0 | xargs -0 md5sum | awk 'h[$1]{ printf "%s\0", $2; next }{ h[$1] = $2 }' | xargs -0 rm

find . -type f -print0: Trova tutti i file e li emette con nomi con terminazione null

xargs -0 md5sum: calcola gli hash in parallelo (regola -nmax-args e -Pmax-procs come desideri, vedi man xargs)

awk 'h[$1]{ printf "%s\0", $2; next }{ h[$1] = $2 }': se c'è una voce nell'hashtable awk che contiene l'md5sum che stiamo attualmente guardando, quindi stampa il nome del file che stiamo attualmente guardando, con terminazione null. Altrimenti, aggiungi il nome file alla tabella hash.

xargs -0 rm: prende le stringhe nulle con pipe e inviate a rm.

Questo è molto più veloce di fdupes.

Se hai un nome file che contiene una nuova riga, awk probabilmente lo troncerà alla nuova riga poiché md5sum separa anche i record da nuove righe.

Questo si basa su /programming/11532157/remove-duplicate-lines-without-sorting e /programming/9133315/how-can-i-output-null-terminated- stringhe-in-awk


1
md5sum * | sort -k1 | uniq -w 32 -d | cut -d' ' -f3 | xargs -I{} sh -c 'rm {}'
  1. accetta tutti i valori md5
  2. ordinarli in modo che i duplicati siano sequenziali per uniq
  3. esegui uniq per produrre solo duplicati
  4. tagliare il nome file dalla riga con il valore md5
  5. chiamare ripetutamente delete sui nomi dei file

0
comm -13 <(md5sum * | sort | uniq -w 32 -d) <(md5sum * | sort | uniq -w 32 -D) | cut -f 3- -d" " | xargs -d '\n' rm

Caratteristiche:

  • Funziona ancora se c'è più di un duplicato per file
  • Funziona ancora se i nomi dei file hanno spazi
  • Funziona ancora se hai eseguito un'alleanza lscon un tipo o--color=always
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.