Estoy tratando de encontrar una manera de verificar dentro de un directorio dado los archivos duplicados (incluso con diferentes nombres) y reemplazarlos con enlaces simbólicos que apuntan a la primera aparición. Lo he intentado fdupes
pero solo enumera esos duplicados.
Ese es el contexto: estoy personalizando un tema de ícono a mi gusto, y he encontrado que muchos íconos, incluso si tienen diferentes nombres y diferentes ubicaciones dentro de su carpeta principal, y se usan para diferentes propósitos, básicamente son los mismos imagen. Dado que aplicar la misma modificación veinte o treinta veces es redundante cuando solo una es realmente necesaria, quiero mantener solo una imagen y vincular todas las demás.
Como ejemplo, si ejecuto fdupes -r ./
dentro del directorio testdir
, podría devolverme los siguientes resultados:
./file1.png
./file2.png
./subdir1/anotherfile.png
./subdir1/subdir2/yetanotherfile.png
Dado este resultado, me gustaría mantener solo el archivo file1.png
, eliminar todos los demás y reemplazarlos con enlaces simbólicos apuntando a él, manteniendo todos los nombres de archivo originales. Por file2.png
lo tanto , conservará su nombre, pero se convertirá en un enlace en file1.png
lugar de ser un duplicado.
Esos enlaces no deben apuntar a una ruta absoluta, sino que deben ser relativos al testdir
directorio padre ; es decir yetanotherfile.png
, se señalará ../../file1.png
, no a/home/testuser/.icons/testdir/file1.png
Estoy interesado en soluciones que involucran una GUI y CLI. No es obligatorio usarlo. fdupes
Lo he citado porque es una herramienta que conozco, pero estoy abierto a soluciones que también usan otras herramientas.
Estoy bastante seguro de que un script bash para manejar todo esto no debería ser tan difícil de crear, pero no soy lo suficientemente experto como para descubrir cómo escribirlo yo mismo.
fuente
v1.51
(Ubuntu 14.04.2 LTS).jdupes
en github.com/jbruchon/jdupes tiene la-L
opción que realiza el enlace duro deseado de conjuntos duplicados.${line//…/}
parte no funcionaba para mí, así que hice una forma más limpia de obtener el primer archivo "maestro" en el enlace duro.rsync
un tipo diferente de sistema de archivos? ¿O si el sistema de archivos no conserva la jerarquía, por ejemplo, es un servidor de respaldo que pone todo bajo control/«machine-name»/...
? ¿O si quieres restaurar desde una copia de seguridad? No puedo ver cómo se van a preservar los enlaces duros aquí. Los enlaces suaves relativos tendrían una mejor oportunidad de sobrevivir, podría pensar.Si no te gustan mucho los scripts, entonces puedo recomendar rdfind . Lo cual escaneará los directorios dados en busca de archivos duplicados y los enlazará de manera rígida o suave. Lo he usado para deduplicar mi directorio de gemas Ruby con gran éxito. Está disponible en Debian / Ubuntu.
fuente
Tuve una situación similar, pero en mi caso el enlace simbólico debería apuntar a una ruta relativa, así que escribí este script de Python para hacer el truco:
Para cada línea de entrada (que es una lista de archivos), el script divide la lista de archivos (espacios en blanco separados), obtiene la ruta relativa de cada archivo al primero y luego crea el enlace simbólico.
fuente
Entonces, la respuesta dada por arnefm (que se ha copiado en Internet) no trata con espacios en los nombres de archivo. He escrito un guión que trata con espacios en archivos.
Lo que esto hace es encontrar duplicados y escribirlos PIPE separados en un archivo llamado 'archivos'.
Luego lee el archivo, línea por línea, en una matriz, y cada elemento de la matriz está delimitado por el PIPE.
Luego itera sobre todos los elementos que no son los primeros de la matriz, reemplazando el archivo con un enlace simbólico al primer elemento.
El archivo externo ('archivos') podría eliminarse, si el comando fdupes se ejecuta en una subshell, eso se lee directamente por el momento, pero de esta manera parece más claro.
fuente
Algunas advertencias por adelantado:
fdupes -1r common/base/dir | while read -r -a line ; do ln -sf $(realpath --relative-to ${line[1]} ${line[0]}) ${line[1]}; done
Si hay más de 2 archivos duplicados (por ejemplo, archivo1 archivo2 archivo3) de los que necesitamos para crear un enlace simbólico para cada par: trate el archivo1, el archivo2 y el archivo1, archivo3 como 2 casos separados:
Gastar esto para manejar automáticamente un número arbitrario de duplicados por línea requerirá un poco más de esfuerzo.
Otro enfoque sería crear primero enlaces simbólicos a rutas absolutas, luego convertirlos:
Esto se basa en la respuesta de @Gilles: /unix//a/100955/77319
fuente