it-swarm.it

C'è un modo semplice per sostituire i file duplicati con hardlink?

Sto cercando un modo semplice (un comando o una serie di comandi, che probabilmente coinvolgono find) per trovare file duplicati in due directory e sostituire i file in una directory con collegamenti fisici dei file nell'altra directory.

Ecco la situazione: questo è un file server su cui più persone memorizzano file audio, ogni utente ha la propria cartella. A volte più persone hanno copie degli stessi identici file audio. In questo momento, questi sono duplicati. Vorrei farlo in modo che siano collegamenti fisici, per risparmiare spazio sul disco rigido.

146
Josh

C'è uno script Perl su http://cpansearch.Perl.org/src/ANDK/Perl-Repository-APC-2.002/eg/trimtrees.pl che fa esattamente quello che vuoi:

Attraversa tutte le directory nominate sulla riga di comando, calcola i checksum MD5 e trova i file con MD5 identico. SE sono uguali, fai un vero confronto se sono davvero uguali, sostituisci il secondo di due file con un collegamento reale al primo.

42
fschmitt

rdfind fa esattamente quello che chiedi (e nell'ordine johny why elenchi). Permette di eliminare i duplicati, sostituirli con collegamenti soft o hard. In combinazione con symlinks puoi anche rendere il collegamento simbolico sia assoluto che relativo. Puoi anche scegliere l'algoritmo di checksum (md5 o sha1).

Poiché è stato compilato, è più veloce della maggior parte delle soluzioni di script: time su una 15 GiB con 2600 file sul mio Mac Mini dal 2009 restituisce questo

9.99s user 3.61s system 66% cpu 20.543 total

(usando md5).

Disponibile nella maggior parte dei gestori di pacchetti (ad es. MacPorts per Mac OS X).

98
d-b

Usa lo strumento fdupes:

fdupes -r /path/to/folder ti dà un elenco di duplicati nella directory (-r lo rende ricorsivo). L'output è simile al seguente:


nomefile1
Nomefile2

nomefile3
Filename4
Filename5


con nomefile1 e nomefile2 identici e nomefile3, nomefile4 e nomefile5 uguali.

51
tante
24
waltinator

Questa è una delle funzioni fornite da "fslint" - http://en.flossmanuals.net/FSlint/Introduction

Fai clic sul pulsante "Unisci":

Screenshot

18
LJ Wobker

Poiché l'obiettivo principale è risparmiare spazio su disco, esiste un'altra soluzione: la deduplicazione (e probabilmente la compressione) a livello di file system. Rispetto alla soluzione di collegamento reale, non ha il problema di influenzare inavvertitamente altri file collegati.

ZFS ha dedup (a livello di blocco, non a livello di file) dalla versione di pool 23 e compressione da molto tempo fa. Se stai usando Linux, puoi provare zfs-Fuse , o se usi BSD, è nativamente supportato.

14
Wei-Yin

Al giorno d'oggi su Linux moderno c'è https://github.com/g2p/bedup che de-duplica su un filesystem btrfs, ma 1) senza l'overhead di scansione, 2) i file possono divergere facilmente ancora dopo.

7
Matthew Bloch
aptitude show hardlink

Descrizione: Hardlink più copie dello stesso file Hardlink è uno strumento che rileva più copie dello stesso file e le sostituisce con hardlink.

L'idea è stata presa da http://code.google.com/p/hardlinkpy/ , ma il codice è stato scritto da zero e concesso in licenza sotto il MIT homepage: http://jak-linux.org/projects/hardlink/

6
Julien Palard

Per trovare file duplicati puoi usare duff.

Duff è un'utilità della riga di comando Unix per trovare rapidamente duplicati in un determinato set di file.

Esegui semplicemente:

duff -r target-folder

Per creare collegamenti fisici a questi file automaticamente, dovrai analizzare l'output di duff con bash o qualche altro scripting linguaggio.

6
Stefan

Ho usato molti degli strumenti di hardlinking per Linux menzionati qui. Anch'io sono bloccato con ext4 fs, su Ubuntu, e ho usato i suoi cp -l e - s per hard/softlinking. Ma recentemente ho notato copia leggera nella pagina man cp, che implicherebbe di risparmiare spazio su disco ridondante fino a una parte viene modificata:

   --reflink[=WHEN]
          control clone/CoW copies. See below

       When  --reflink[=always]  is specified, perform a lightweight copy, where the 
data blocks are copied only when modified.  If this is not possible the
       copy fails, or if --reflink=auto is specified, fall back to a standard copy.
4
Marcos

jdupes è stato menzionato in un commento, ma merita una sua risposta, poiché è probabilmente disponibile nella maggior parte delle distribuzioni e funziona abbastanza velocemente (ha appena liberato 2,7 GB di una partizione da 158 GB piena al 98% (unità SSD) in circa un minuto) :

jdupes -rL /foo/bar

Mi sembra che controllare prima il nome del file potrebbe velocizzare le cose. Se due file non hanno lo stesso nome file, in molti casi non li considero duplicati. Sembra che il metodo più rapido sarebbe quello di confrontare, in ordine:

  • nome del file
  • dimensione
  • checksum md5
  • contenuto byte

Qualche metodo fa questo? Guarda duff, fdupes, rmlint, fslint, ecc.

Il seguente metodo è stato votato per primo su commandlinefu.com : Trova file duplicati (prima in base alle dimensioni, quindi all'hash MD5)

È possibile aggiungere il confronto dei nomi di file come primo passo, la dimensione come secondo passo?

find -not -empty -type f -printf "%s\n" | sort -rn | uniq -d | \
  xargs -I{} -n1 find -type f -size {}c -print0 | xargs -0 md5sum | \
  sort | uniq -w32 --all-repeated=separate
4
johny why

Dato che non sono un fan di Perl, ecco una versione bash:

#!/bin/bash

DIR="/path/to/big/files"

find $DIR -type f -exec md5sum {} \; | sort > /tmp/sums-sorted.txt

OLDSUM=""
IFS=$'\n'
for i in `cat /tmp/sums-sorted.txt`; do
 NEWSUM=`echo "$i" | sed 's/ .*//'`
 NEWFILE=`echo "$i" | sed 's/^[^ ]* *//'`
 if [ "$OLDSUM" == "$NEWSUM" ]; then
  echo ln -f "$OLDFILE" "$NEWFILE"
 else
  OLDSUM="$NEWSUM"
  OLDFILE="$NEWFILE"
 fi
done

Questo trova tutti i file con lo stesso checksum (siano essi grandi, piccoli o già collegati) e li collega insieme.

Questo può essere notevolmente ottimizzato per ripetute esecuzioni con flag di ricerca aggiuntivi (ad es. Dimensione) e una cache di file (quindi non è necessario ripetere i checksum ogni volta). Se qualcuno è interessato alla versione più intelligente e più lunga, posso pubblicarla.

NOTA: Come accennato in precedenza, i collegamenti fissi funzionano fintanto che i file non necessitano mai di modifiche o devono essere spostati tra i filesystem.

3
seren

Se vuoi sostituire i duplicati con Hard Link su Mac o qualsiasi sistema basato su UNIX, puoi provare SmartDupe http://sourceforge.net/projects/smartdupe/ lo sto sviluppando

1
islam

Ho realizzato uno script Perl che fa qualcosa di simile a quello di cui stai parlando:

http://Pastebin.com/U7mFHZU7

Fondamentalmente, attraversa solo una directory, calcolando la somma SHA1 dei file in essa contenuti, eseguendo l'hashing e collegando le corrispondenze. È utile in molte, molte occasioni.

1
amphetamachine

Le applicazioni FSLint ( http://www.pixelbeat.org/fslint/ ) possono trovare tutti i file uguali in qualsiasi cartella (in base al contenuto) e creare hardlink. Provaci!

Jorge Sampaio

1

I collegamenti reali potrebbero non essere l'idea migliore; se un utente modifica il file, influisce su entrambi. Tuttavia, l'eliminazione di un collegamento reale non cancella entrambi i file. Inoltre, non sono del tutto sicuro se i collegamenti hardware occupino la stessa quantità di spazio (sul disco rigido, non sul sistema operativo) delle copie multiple dello stesso file; secondo Windows (con l'estensione Shell di collegamento), lo fanno. Certo, è Windows, non Unix ...

La mia soluzione sarebbe quella di creare un file "comune" in una cartella nascosta e sostituire i duplicati effettivi con collegamenti simbolici ... quindi, i collegamenti simbolici sarebbero incorporati con metadati o flussi di file alternativi che registra solo i due "file" sono diversi l'uno dall'altro, come se una persona volesse cambiare il nome del file o aggiungere copertine personalizzate o qualcos'altro del genere; potrebbe anche essere utile al di fuori delle applicazioni di database, come avere più versioni dello stesso gioco o software installato e testarle indipendentemente con anche le più piccole differenze.

0
Amaroq Starwind

Se esegui hardlink, presta attenzione ai diritti su quel file. Avviso, proprietario, gruppo, modalità, attributi estesi, ora e ACL (se si utilizza questo) sono memorizzati in INODE. Solo i nomi dei file sono diversi perché sono memorizzati nella struttura della directory e altri punti sulle proprietà INODE. Questa causa, tutti i nomi di file collegati allo stesso inode, hanno gli stessi diritti di accesso. Dovresti impedire la modifica di quel file, perché qualsiasi utente può danneggiare il file ad altri. È semplice. È sufficiente che qualsiasi utente inserisca altri file con lo stesso nome. Il numero di nodo viene quindi salvato e il contenuto del file originale viene distrutto (sostituito) per tutti i nomi hardlink.

Il modo migliore è la deduplicazione a livello di filesystem. Puoi usare BTRFS (molto popolare l'ultima volta), OCFS o in questo modo. Guarda la pagina: https://en.wikipedia.org/wiki/Comparison_of_file_systems , in particolare nella tabella Funzionalità e deduplicazione dei dati delle colonne. Puoi fare clic e ordinare :)

Guarda in particolare il filesystem ZFS. Questo è disponibile come Fuse, ma in questo modo è molto lento. Se si desidera il supporto nativo, consultare la pagina http://zfsonlinux.org/ . Quindi è necessario patch kernel e quindi installare zfs tools per managament. Non capisco, perché Linux non supporta come driver, è un modo per molti altri sistemi operativi/kernel.

I file system supportano la deduplicazione in 2 modi, file deduplicati o blocchi. ZFS supporta il blocco. Ciò significa che è possibile deduplicare lo stesso contenuto che si ripete nello stesso file. L'altro modo è il momento in cui i dati vengono deduplicati, questo può essere online (zfs) o offline (btrfs).

Si noti che la deduplicazione consuma RAM. Questo è il motivo per cui la scrittura di file sul volume ZFS montato con Fuse causa prestazioni notevolmente lente. Questo è descritto nella documentazione. Ma puoi impostare on/off la deduplicazione sul volume online. Se vedi che tutti i dati devono essere deduplicati, devi semplicemente attivare la deduplicazione, riscrivere alcuni file su qualsiasi temporaneo e infine sostituirli. dopo questo è possibile disattivare la deduplicazione e ripristinare le prestazioni complete. Naturalmente, è possibile aggiungere alla memoria tutti i dischi cache. Questo può essere molto veloce ruotare dischi o dischi SSD. Naturalmente questo può essere un disco molto piccolo. Nel lavoro reale questo è sostitutivo di RAM :)

Sotto Linux dovresti prenderti cura di ZFS perché non tutto funziona come dovrebbe, specialmente quando gestisci il filesystem, fai uno snapshot ecc. Ma se fai la configurazione e non la cambi, tutto funziona correttamente. Altrimenti, dovresti cambiare Linux in opensolaris, supporta nativamente ZFS :) Ciò che è molto bello con ZFS è, questo funziona sia come filesystem che come gestore volumen simile a LVM. Non è necessario quando si utilizza ZFS. Vedi la documentazione se vuoi saperne di più.

Notare la differenza tra ZFS e BTRFS. ZFS è più vecchio e più maturo, purtroppo solo sotto Solaris e OpenSolaris (purtroppo strangolato da Oracle). BTRFS è più giovane, ma l'ultima volta supportato molto bene. Raccomando kernel fresco. ZFS ha la deduplicazione online, che causa rallentamenti delle scritture, perché tutto è calcolato online. BTRFS supporta la dedupliazione off-line. Quindi ciò consente di risparmiare prestazioni, ma quando Host non ha nulla a che fare, si esegue periodicamente lo strumento per effettuare la deduplicazione. E BTRFS è creato nativamente sotto Linux. Forse è meglio FS per te :)

0
Znik

Il modo più semplice è usare il programma speciale dupeGuru

dupeGuru Preferences Screenshot

come documentazione dice

Opzioni di eliminazione

Queste opzioni influenzano il modo in cui avviene la cancellazione duplicata. Il più delle volte, non è necessario abilitare nessuno di essi.

Collega i file eliminati:

I file eliminati vengono sostituiti da un collegamento al file di riferimento. Puoi scegliere di sostituirlo con un collegamento simbolico o un collegamento reale. ... un collegamento simbolico è un collegamento al percorso del file. Se il file originale viene eliminato o spostato, il collegamento viene interrotto. Un hardlink è un collegamento al file stesso. Quel collegamento è buono come un file "reale". Solo quando tutti i collegamenti a un file vengono eliminati, il file stesso viene eliminato.

Su OSX e Linux, questa funzione è completamente supportata, ma in Windows è un po 'complicata. Windows XP non lo supporta, ma Vista e versioni successive lo supportano. Tuttavia, affinché la funzione funzioni, dupeGuru deve funzionare con privilegi di amministratore.