Buscar archivos que no existen en otro directorio

Buscar archivos que no existen en otro directorio

Necesito encontrar todos los archivos que existen en cualquier lugar de dir1, pero que no existen en ningún lugar de dir2. dir1y dir2puede tener una estructura diferente, por lo que diff -rno funciona bien.

Respuesta1

Intente hacer una lista de archivos sin ruta. De esa manera, puede comparar dos directorios. Sin embargo, todos los nombres de archivos deberían ser diferentes. Si tiene el mismo nombre de archivo repetido en dir1 en diferentes subdirectorios, eliminar la ruta eliminará la unicidad del nombre de archivo. Puede obtener una lista de cada directorio sin nombres de ruta como este:

find dir1/ -exec basename {} \; | sort
find dir2/ -exec basename {} \; | sort

Todos juntos se verían así

diff <(find dir1/ -exec basename {} \; | sort) <(find dir2/ -exec basename {} \; | sort)

Veo que hay un comentario que sugiere el uso de fdupes. fdupesSi definitivamente es una mejor solución.

Respuesta2

Un método burdo podría ser el uso de md5sum. Solo tenga en cuenta que los archivos con longitud cero siempre se verán como duplicados, por lo que es posible que desee almacenar findsolo archivos con un tamaño de al menos un byte.

find /first/path -type f -exec md5sum -b \{\} \; > /tmp/md5-path1.txt
cut -b1-32 < /tmp/md5-path1-short.txt
find /second/path -type f -exec md5sum -b \{\} \; > /tmp/md5-path2.txt
cut -b1-32 < /tmp/md5-path2-short.txt

Archivos en la ruta1 que no están en la ruta2 (elimine la opción '-v'

grep /tmp/md5-path1.txt -v -F -f /tmp/md5/path2-short.txt

Nivel CYA: profesional

El 32 anterior se debe a que los hashes MD5 tienen 32 bytes de longitud. Si usara, digamos, sha1sum, que tiene una probabilidad aún menor de colisiones, entonces usaría una longitud de 40; sha224sumrequiere 56, sha256sumrequiere 64 y sha512sum128.

Nivel CYA: paranoico

Es posible que esto no funcione en algunos esquemas de almacenamiento en caché en los que los metadatos se guardan en archivos.cuyo nombre contiene el hash del archivo original.

(Esto realmente me pasó con una instalación de Wordpress + Magento hace años, donde queríamos migrar un caché de artículos enorme y eliminar las entradas obsoletas).

En este caso, tendría que usar un esquema de hash diferente (solución rápida) para evitar grepdevolver falsos positivos, confundiendo la entrada de metadatos con el archivo original (por lo tanto, use SHA1 si el caché usa MD5 o viceversa); o usar sedpara reescribir todas las líneas en los archivos "cortos" para agregar un "^" al principio, convirtiéndolo así en una expresión regular anclada y eliminando la -Fbandera greppara procesar el archivo como expresiones regulares en lugar de cadenas simples.

Respuesta3

Entonces, la solución parcial que encontré es:

find dir1 -type f | grep -vxFf <(fdupes -r dir1 dir2)

pero digo "parcial", porque si hay duplicados en dir1, no se mostrarán, por lo que debes ejecutarlo fdupes -r dir1primero.

información relacionada