¿Hay una manera fácil de reemplazar archivos duplicados con enlaces duros?


137

Estoy buscando una manera fácil (un comando o una serie de comandos, probablemente involucrados find) para encontrar archivos duplicados en dos directorios y reemplazar los archivos en un directorio con enlaces duros de los archivos en el otro directorio.

Aquí está la situación: este es un servidor de archivos en el que varias personas almacenan archivos de audio, cada usuario tiene su propia carpeta. A veces, varias personas tienen copias de los mismos archivos de audio. En este momento, estos son duplicados. Me gustaría hacerlo para que sean enlaces duros, para ahorrar espacio en el disco duro.


20
Un problema con el que se puede encontrar con los enlaces duros es que si alguien decide hacer algo en uno de sus archivos de música que haya vinculado de manera rígida, podría estar afectando inadvertidamente el acceso de otras personas a su música.
Steven D

44
Otro problema es que dos archivos diferentes que contienen "Some Really Great Tune", incluso si se toman de la misma fuente con el mismo codificador, probablemente no serán idénticos bit por bit.
msw

3
una mejor solución podría ser tener una carpeta de música pública ...
Stefan


1
@tante: El uso de enlaces simbólicos no resuelve ningún problema. Cuando un usuario "elimina" un archivo, la cantidad de enlaces a este disminuye, cuando el recuento llega a cero, los archivos se eliminan realmente, eso es todo. Por lo tanto, la eliminación no es un problema con los archivos enlazados, el único problema es un usuario que intenta editar el archivo (de hecho, no es probable) o sobrescribirlo (muy posible si está conectado).
maaartinus

Respuestas:


41

Hay un script perl en http://cpansearch.perl.org/src/ANDK/Perl-Repository-APC-2.002/eg/trimtrees.pl que hace exactamente lo que desea:

Recorre todos los directorios nombrados en la línea de comando, calcula sumas de comprobación MD5 y encuentra archivos con MD5 idéntico. SI son iguales, haga una comparación real si son realmente iguales, reemplace el segundo de dos archivos con un enlace rígido al primero.


Suena perfecto , gracias !! ¡Lo intentaré y aceptaré si funciona como se describe!
Josh

3
Esto hizo exactamente lo que pedí. Sin embargo, creo que ZFS con dedup eventualmente será la forma de hacerlo, ya que descubrí que los archivos tenían pequeñas diferencias, por lo que solo unos pocos podían vincularse.
Josh

11
Voté esto, pero después de investigar un poco más, no lo hice. rdfindestá disponible a través de los administradores de paquetes para TODAS las plataformas principales (os x, linux, (cyg) win, solaris), y funciona a una velocidad nativa increíble. Así que mira la respuesta a continuación.
oligofren

@oligofren Estaba pensando lo mismo, pero luego pegué [Errno 31] Too many links. Esta secuencia de comandos parece ser lo único que maneja eso.
phunehehe

55
La suma de verificación de cada archivo, en lugar de solo los archivos donde existe al menos otro con un tamaño idéntico, es innecesariamente ineficiente (y innecesariamente propenso a colisiones hash).
Charles Duffy

85

rdfindhace exactamente lo que pides (y en el orden johny por qué las listas). Permite eliminar duplicados, reemplazarlos con enlaces blandos o duros. Combinado con symlinksusted también puede hacer que el enlace simbólico sea absoluto o relativo. Incluso puede elegir el algoritmo de suma de verificación (md5 o sha1).

Dado que está compilado, es más rápido que la mayoría de las soluciones con script: timeen una carpeta de 15 GiB con 2600 archivos en mi Mac Mini de 2009, devuelve esto

9.99s user 3.61s system 66% cpu 20.543 total

(usando md5).

Disponible en la mayoría de los controladores de paquetes (por ejemplo, MacPorts para Mac OS X).


11
+1 Lo usé rdfindy me encantó. Tiene una -dryrun trueopción que le permitirá saber lo que habría hecho. Reemplazar duplicados con enlaces duros es tan simple como -makehardlinks true. Produjo un buen registro y me dejó saber cuánto espacio se liberó. Además, según el punto de referencia del autor , rdfind es más rápido que duff y fslint.
Daniel Trebbien

oooh, bien Solía ​​usar fdupes, pero su opción -L para ductos de hardlinking falta en el último Ubuntu 14.10. Era bastante lento y no existía para Homebrew en OSX, por lo que esta respuesta es mucho mejor. ¡Gracias!
oligofren

Algoritmo muy inteligente y rápido.
ndemou

2
Sospecho que el rendimiento de esta herramienta tiene más que ver con el algoritmo y menos con una herramienta compilada o un script. Para este tipo de operación, el disco será el cuello de botella casi todo el tiempo. Siempre que las herramientas con secuencias de comandos se aseguren de que tengan una operación de E / S asíncrona en progreso mientras queman la CPU en las sumas de verificación, deben funcionar tan bien como un binario nativo.
cdhowie

rdfind depende mucho del nuevo sistema operativo y el compilador. (no se ejecutará en CentOS 6.x sin una reconstrucción casi completa de las herramientas de desarrollo)
Cosmo F

49

Usa la fdupesherramienta:

fdupes -r /path/to/folderle da una lista de duplicados en el directorio (-r lo hace recursivo). El resultado se ve así:


filename1
filename2

filename3
filename4
filename5


con filename1 y filename2 son idénticos y filename3, filename4 y filename5 también son idénticos.


1
Nota de Ubuntu: a partir de septiembre de 2013, no ha tenido una versión estable (está en 1.50-PR2-3), por lo que la actualización aún no aparece en ubuntu.
Stuart Axon

11
Acabo de intentar instalar fdupes_1.50-PR2-4 en Ubuntu y Debian, ninguno de los dos tiene el indicador -L. Afortunadamente, construir desde github.com/tobiasschulz/fdupes fue súper fácil.
neu242

3
Tratar rdfind- como fdupes, pero más rápido y disponible en OS X y Cygwin también.
oligofren

66
fdupesparece que solo encuentra duplicados, no los reemplaza con enlaces duros, por lo que no es una respuesta a la pregunta IMO.
Calimo

2
Hay una herramienta similar llamada jdupesque se basa en fdupes, pero también puede reemplazar los archivos duplicados con enlaces simbólicos ( -l), enlaces duros ( -L) o instruir a btrfs para deduplicar los bloques en el nivel del sistema de archivos ( -Bsi está usando btrfs).
Marius Gedminas

23

1
Buen toque, estoy utilizando de forma regular code.google.com/p/hardlinkpy pero esto no se ha actualizado durante un tiempo ...
meduz

2
Esto parece ser similar al original hardlinken Fedora / RHEL / etc.

1
hardlinkahora es un binario nativo en muchos sistemas de paquetes de Linux (desde ~ 2014) y extremadamente rápido. Para archivos de 1,2M (320GB), solo tomó 200 segundos (enlazando aproximadamente el 10% de los archivos).
Marcel Waldvogel

FWIW, lo anterior hardlinkfue creado por Julian Andres Klode mientras que el Fedora hardlinkfue creado por Jakub Jelinek (fuente: pagure.io/hardlink - nombre del paquete Fedora: hardlink)
maxschlepzig

18

Esta es una de las funciones proporcionadas por "fslint" - http://en.flossmanuals.net/FSlint/Introduction

Haga clic en el botón "Fusionar":

Captura de pantalla


44
El -m enlazará los duplicados juntos, -d eliminará todos menos uno, y -t ejecutará en seco, imprimiendo lo que haría
Azendale

1
En Ubuntu, esto es lo que debe hacer: sudo apt-get install fslint /usr/share/fslint/fslint/findup -m /your/directory/tree(el directorio / usr / share / fslint / fslint / no está en $ PATH por defecto)
Jocelyn

14

Como su objetivo principal es ahorrar espacio en el disco, existe otra solución: la desduplicación (y probablemente la compresión) en el nivel del sistema de archivos. En comparación con la solución de enlace duro, no tiene el problema de afectar inadvertidamente a otros archivos vinculados.

ZFS tiene dedup (nivel de bloque, no nivel de archivo) desde la versión 23 del grupo y compresión desde hace mucho tiempo. Si está utilizando Linux, puede probar zfs-fuse , o si usa BSD, es compatible de forma nativa.


Esta es probablemente la forma en que iré eventualmente, sin embargo, ¿deduplica la implementación de ZFS de BSD? Pensé que no.
Josh

Además, el sistema de archivos HAMMER en DragonFlyBSD tiene soporte de deduplicación.
hhaamu

14
ZFS dedup no es amigo de nadie. Cuando ZFS recomienda 1 Gb de ram por 1 TB de espacio en disco utilizable, estás loco si intentas usar dedup con menos de 32 Gb de ram por 1 TB de espacio en disco utilizable. Eso significa que para un espejo de 1Tb, si no tiene 32 Gb de ram, es probable que tarde o temprano encuentre condiciones de bomba de memoria que detendrán la máquina debido a la falta de ram. He estado allí, hecho eso, todavía recuperándome del TEPT.
killermist

44
Para evitar los requisitos excesivos de RAM con la deduplicación en línea (es decir, verifique cada escritura), btrfsutilice la deduplicación por lotes o fuera de línea (ejecútela siempre que lo considere útil / necesario) btrfs.wiki.kernel.org/index.php/Deduplication
Marcel Waldvogel

3
Actualización siete años después: finalmente me mudé a ZFS e intenté la deduplicación; descubrí que los requisitos de RAM eran de hecho demasiado altos. El uso astuto de las instantáneas de ZFS proporcionó la solución que terminé usando. (Copie la música, la instantánea y el clon de un usuario, copie la música del segundo usuario en el clon rsync --inplacepara que solo se almacenen los bloques modificados)
Josh


5

Para encontrar archivos duplicados puede usar duff .

Duff es una utilidad de línea de comandos de Unix para encontrar rápidamente duplicados en un conjunto de archivos dado.

Simplemente ejecute:

duff -r target-folder

Para crear enlaces duros a esos archivos automáticamente, deberá analizar la salida de duff con bash o algún otro lenguaje de secuencias de comandos.


Sin embargo, es muy lento: consulte rdfind.pauldreik.se/#g0.6
ndemou el

5
aptitude show hardlink

Descripción: enlaces múltiples copias del mismo archivo Hardlink es una herramienta que detecta múltiples copias del mismo archivo y las reemplaza por enlaces duros.

La idea ha sido tomada de http://code.google.com/p/hardlinkpy/ , pero el código ha sido escrito desde cero y con licencia bajo la licencia MIT. Página de inicio: http://jak-linux.org/projects/hardlink/


El único programa mencionado aquí disponible para Gentoo sin desenmascarar y con soporte de enlace duro, ¡gracias!
Jorrit Schippers

4

He usado muchas de las herramientas de hardlinking para Linux mencionadas aquí. Yo también estoy atrapado con ext4 fs, en Ubuntu, y he estado usando sus cp -l y -s para hard / softlinking. Pero últimamente noté la copia ligera en la página de manual de cp , lo que implicaría ahorrar espacio en disco redundante hasta que se modifique un lado:

   --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.

Creo que actualizaré mi cpalias para incluir siempre el --reflink=autoparámetro ahora
Marcos

1
¿Ext4 realmente es compatible --reflink?

77
Esto es compatible con btrfs y OCFS2. Solo es posible en sistemas de archivos de copia en escritura, que ext4 no es. btrfs realmente se está formando. Me encanta usarlo debido a los enlaces de referencia y las instantáneas, lo que hace que tenga menos miedo de realizar operaciones masivas en grandes árboles de archivos.
clacke

3

Me parece que verificar el nombre del archivo primero podría acelerar las cosas. Si dos archivos carecen del mismo nombre de archivo, en muchos casos no los consideraría duplicados. Parece que el método más rápido sería comparar, en orden:

  • nombre del archivo
  • Talla
  • suma de comprobación md5
  • contenido de bytes

¿Algún método hace esto? Mira duff, fdupes, rmlint, fslint, etc.

El siguiente método fue el más votado en commandlinefu.com : Buscar archivos duplicados (basado primero en el tamaño, luego en hash MD5)

¿Se puede agregar la comparación de nombre de archivo como primer paso, el tamaño como segundo paso?

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

3
Lo he utilizado duff, fdupesy rmlint, y recomiendo a los lectores a mirar a la tercera parte de éstos . Tiene un excelente conjunto de opciones (y documentación). Con él, pude evitar mucho del procesamiento posterior que necesitaba usar con las otras herramientas.
dubiousjim

3
En mi práctica, el nombre de archivo es el factor menos confiable para mirar, y lo he eliminado por completo de cualquier esfuerzo que realice para eliminar el duplicado. ¿Cuántos install.sharchivos se pueden encontrar en un sistema activo? No puedo contar la cantidad de veces que guardé un archivo y tuve un choque de nombres, con un cambio de nombre sobre la marcha para guardarlo. Otro lado: no tengo idea de cuántas veces he descargado algo de diferentes fuentes, en diferentes días, solo para descubrir que son el mismo archivo con diferentes nombres. (Lo que también mata la fiabilidad de la marca de tiempo). 1: Tamaño, 2: Resumen, 3: Contenido de bytes.
Gypsy Spellweaver

@GypsySpellweaver: (1) depende del caso de uso personal, ¿no le parece? En mi caso, tengo varias restauraciones de múltiples copias de seguridad, donde existen archivos con el mismo nombre y contenido en diferentes carpetas de restauración. (2) Su comentario parece suponer que solo se compara el nombre de archivo . No estaba sugiriendo eliminar otros controles.
johny por qué el

2

Como no soy fanático de Perl, aquí hay una versión 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

Esto busca todos los archivos con la misma suma de comprobación (ya sean enlaces grandes, pequeños o ya con enlaces duros) y los une entre sí.

Esto se puede optimizar en gran medida para ejecuciones repetidas con marcas de búsqueda adicionales (por ejemplo, tamaño) y un caché de archivos (para que no tenga que rehacer las sumas de verificación cada vez). Si alguien está interesado en la versión más inteligente y más larga, puedo publicarla.

NOTA: Como se mencionó anteriormente, los enlaces duros funcionan siempre y cuando los archivos nunca necesiten modificación o para moverse a través de los sistemas de archivos.


¿Cómo puedo cambiar su secuencia de comandos, de modo que, en lugar de marcarlo, simplemente borre los archivos duplicados y agregue una entrada a un archivo CSV? El archivo borrado -> Archivo alineado. . ???
MR.GEWA

Seguro. La línea del enlace duro: echo ln -f "$ OLDFILE" "$ NEWFILE" Simplemente reemplaza el archivo duplicado con un enlace duro, para que pueda cambiarlo por el $ NEWFILE en su lugar.
seren

y ¿cómo en la siguiente línea, escribir en algún archivo de texto de alguna manera $ OLDFILE-> NEWFILE ???
MR.GEWA

Ahh, cierto. Sí, agregue una línea después del rm como: echo "$ NEWFILE" >> /var/log/deleted_duplicate_files.log
seren

2
No vuelvas a inventar la rueda. Hay soluciones más maduras disponibles, como rdfind, que funcionan a velocidades nativas y solo requieren brew install rdfindo apt-get install rdfindpara instalarse.
oligofren

1

Hice un script de Perl que hace algo similar a lo que estás hablando:

http://pastebin.com/U7mFHZU7

Básicamente, solo atraviesa un directorio, calculando la suma SHA1 de los archivos que contiene, dividiéndolo en hash y vinculando las coincidencias. Ha sido útil en muchas, muchas ocasiones.


2
Espero poder probar esto pronto ... ¿por qué no subirlo en CPAN ... Aplicación :: relink o algo?
xenoterracide

2
@xenoterracide: debido a todas las soluciones similares y más maduras que ya existen. Vea las otras respuestas, especialmente rdfind.
oligofren

1
@oligofren No dudo que existan mejores soluciones. TMTOWTDI, supongo.
anfetamáquina


1

Las aplicaciones FSLint ( http://www.pixelbeat.org/fslint/ ) pueden encontrar todos los archivos iguales en cualquier carpeta (por contenido) y crear enlaces duros. ¡Darle una oportunidad!

Jorge Sampaio


Cuelga el escaneo del disco duro ext3 casi completo de 1TB y hace que todo el sistema se detenga. Abortado después de 14 horas de "búsqueda"
Angsuman Chakraborty

1

jdupes se ha mencionado en un comentario, pero merece su propia respuesta, ya que probablemente esté disponible en la mayoría de las distribuciones y se ejecute bastante rápido (solo liberó 2,7 GB de una partición completa de 98% de 158 GB (unidad SSD) en aproximadamente un minuto):

jdupes -rL /foo/bar

0

Si va a hacer enlaces duros, preste atención a los derechos en ese archivo. Aviso, propietario, grupo, modo, atributos extendidos, tiempo y ACL (si usa esto) se almacenan en INODE. Solo los nombres de los archivos son diferentes porque se almacenan en la estructura del directorio y otros puntos a las propiedades INODE. Esta causa, todos los nombres de archivo vinculados al mismo inodo, tienen los mismos derechos de acceso. Debe evitar la modificación de ese archivo, ya que cualquier usuario puede dañar el archivo a otro. Es simple. Es suficiente, cualquier usuario pone otro archivo con el mismo nombre. El número de inoode se guarda y el contenido del archivo original se destruye (reemplaza) para todos los nombres enlazados.

La mejor manera es la deduplicación en la capa del sistema de archivos. Puede usar BTRFS (muy popular la última vez), OCFS o de esta manera. Mire la página: https://en.wikipedia.org/wiki/Comparison_of_file_systems , especialmente en la tabla Características y deduplicación de datos de columna. Puedes hacer clic y ordenar :)

Mire especialmente al sistema de archivos ZFS. Está disponible como FUSE, pero de esta manera es muy lento. Si desea soporte nativo, mire la página http://zfsonlinux.org/ . Luego debe parchear el kernel y luego instalar las herramientas zfs para la administración. No entiendo, por qué Linux no es compatible como controladores, es la forma para muchos otros sistemas operativos / núcleos.

Los sistemas de archivos admiten la deduplicación de 2 formas, deduplicar archivos o bloques. ZFS admite bloque. Esto significa que los mismos contenidos que se repiten en el mismo archivo pueden deduplicarse. Otra forma es cuando los datos se deduplican, esto puede ser en línea (zfs) o fuera de línea (btrfs).

Aviso, la deduplicación consume RAM. Es por eso que escribir archivos en el volumen ZFS montado con FUSE, causa un rendimiento dramáticamente lento Esto se describe en la documentación. Pero en línea puede activar / desactivar la deduplicación en volumen. Si ve que algún dato debe ser deduplicado, simplemente active la deduplicación, reescriba algún archivo en cualquier temporal y finalmente reemplácelo. después de esto, puede desactivar la deduplicación y restaurar el rendimiento completo. Por supuesto, puede agregar al almacenamiento cualquier disco de caché. Esto puede ser discos de rotación muy rápidos o discos SSD. Por supuesto, esto puede ser discos muy pequeños. En el trabajo real, este es el reemplazo de RAM :)

En Linux, debe tener cuidado con ZFS porque no todo funciona como debería, especialmente cuando administra el sistema de archivos, toma una instantánea, etc., pero si realiza la configuración y no la cambia, todo funciona correctamente. De otra manera, debe cambiar Linux a opensolaris, es compatible de forma nativa con ZFS :) Lo que es muy bueno con ZFS es que funciona tanto como sistema de archivos como administrador de volumen similar a LVM. No lo necesita cuando usa ZFS. Consulte la documentación si desea saber más.

Observe la diferencia entre ZFS y BTRFS. ZFS es más antiguo y más maduro, desafortunadamente solo bajo Solaris y OpenSolaris (desafortunadamente estrangulado por Oracle). BTRFS es más joven, pero la última vez es muy bueno. Recomiendo kernel fresco. ZFS tiene deduplicación en línea, lo que causa ralentizaciones de escritura, porque todo se calcula en línea. BTRFS admite deduplicación fuera de línea. Entonces esto ahorra rendimiento, pero cuando el host no tiene nada que hacer, ejecuta periódicamente la herramienta para realizar la deduplicación. Y BTRFS se crea de forma nativa en Linux. Tal vez esto es mejor FS para ti :)


1
Me gusta el enfoque de deduplicación fuera de línea (o por lotes ) btrfs. Excelente discusión de las opciones (incluida la cp --reflinkopción) aquí: btrfs.wiki.kernel.org/index.php/Deduplication
Marcel Waldvogel

ZFS no es solo Solaris u OpenSolaris. Es compatible de forma nativa en FreeBSD. Además, ZFS en Linux está basado en el controlador del dispositivo; ZFS en FUSE es una cosa diferente.
KJ Seefried

0

Los enlaces duros pueden no ser la mejor idea; Si un usuario cambia el archivo, afecta a ambos. Sin embargo, eliminar un enlace duro no elimina ambos archivos. Además, no estoy completamente seguro de que los enlaces duros ocupen la misma cantidad de espacio (en el disco duro, no en el sistema operativo) que varias copias del mismo archivo; según Windows (con la extensión Link Shell), lo hacen. De acuerdo, eso es Windows, no Unix ...

Mi solución sería crear un archivo "común" en una carpeta oculta y reemplazar los duplicados reales con enlaces simbólicos ... luego, los enlaces simbólicos se incrustarían con metadatos o secuencias de archivos alternativas que solo registran los dos "archivos" son diferentes entre sí, como si una persona quiere cambiar el nombre de archivo o agregar una carátula personalizada o algo así; incluso podría ser útil fuera de las aplicaciones de bases de datos, como tener instaladas varias versiones del mismo juego o software y probarlas de forma independiente, incluso con las más pequeñas diferencias.


0

La forma más fácil es usar el programa especial dupeGuru

Captura de pantalla de las preferencias de dupeGuru

como dice la documentación

Opciones de borrado

Estas opciones afectan cómo se lleva a cabo la eliminación duplicada. La mayoría de las veces, no necesita habilitar ninguno de ellos.

Vincular archivos eliminados:

Los archivos eliminados se reemplazan por un enlace al archivo de referencia. Tiene la opción de reemplazarlo con un enlace simbólico o un enlace duro. ... un enlace simbólico es un acceso directo a la ruta del archivo. Si el archivo original se elimina o se mueve, el enlace está roto. Un enlace duro es un enlace al archivo en sí. Ese enlace es tan bueno como un archivo "real". Solo cuando se eliminan todos los enlaces duros a un archivo, se elimina el archivo mismo.

En OSX y Linux, esta característica es totalmente compatible, pero en Windows, es un poco complicado. Windows XP no lo admite, pero Vista y versiones posteriores lo admiten. Sin embargo, para que la función funcione, dupeGuru debe ejecutarse con privilegios administrativos.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.