J'essaie de trouver un moyen de vérifier dans un répertoire donné des fichiers en double (même avec des noms différents) et de les remplacer par des liens symboliques pointant vers la première occurrence. J'ai essayé avec fdupes
mais il répertorie simplement ces doublons.
C'est le contexte: je personnalise un thème d'icônes à mon goût, et j'ai constaté que de nombreuses icônes, même si elles ont des noms différents et des emplacements différents dans leur dossier parent, et sont utilisées à des fins différentes, sont fondamentalement les mêmes image. Puisqu'appliquer la même modification vingt ou trente fois est redondant quand une seule est vraiment nécessaire, je veux garder une seule image et créer un lien symbolique entre toutes les autres.
Par exemple, si je cours fdupes -r ./
dans le répertoire testdir
, cela pourrait me renvoyer les résultats suivants:
./file1.png
./file2.png
./subdir1/anotherfile.png
./subdir1/subdir2/yetanotherfile.png
Compte tenu de cette sortie, je voudrais conserver uniquement le fichier file1.png
, supprimer tous les autres et les remplacer par des liens symboliques pointant vers lui, tout en conservant tous les noms de fichiers d'origine. Ainsi file2.png
conservera son nom, mais deviendra un lien vers file1.png
au lieu d'être un doublon.
Ces liens ne doivent pas pointer vers un chemin absolu, mais doivent être relatifs au parent testdir
répertoire ; c'est-à yetanotherfile.png
- dire pointera vers ../../file1.png
, pas vers/home/testuser/.icons/testdir/file1.png
Je m'intéresse à la fois aux solutions qui impliquent une interface graphique et une CLI. Il n'est pas obligatoire de l'utiliser, fdupes
je l'ai cité car c'est un outil que je connais, mais je suis ouvert à des solutions qui utilisent également d'autres outils.
Je suis à peu près sûr qu'un script bash pour gérer tout cela ne devrait pas être si difficile à créer, mais je ne suis pas assez expert pour savoir comment l'écrire moi-même.
la source
v1.51
(Ubuntu 14.04.2 LTS).jdupes
sur github.com/jbruchon/jdupes a l'-L
option qui fait la liaison dure souhaitée des jeux en double.${line//…/}
partie ne fonctionnait pas pour moi, j'ai donc fait un moyen plus propre d'obtenir le premier fichier "maître" en lien dur.rsync
un autre type de système de fichiers? Ou si le système de fichiers ne préserve pas la hiérarchie, par exemple, c'est un serveur de sauvegarde qui met tout sous/«machine-name»/...
? Ou si vous souhaitez restaurer à partir d'une sauvegarde? Je ne vois pas comment les liens physiques vont être conservés ici. Les liens logiciels relatifs auraient plus de chances de survivre, je pense.Si vous n'aimez pas beaucoup les scripts, je peux recommander rdfind . Qui analysera les répertoires donnés pour les fichiers en double et les liera entre eux en dur ou en soft. Je l'ai utilisé pour dédupliquer mon répertoire Ruby Gems avec beaucoup de succès. Il est disponible dans Debian / Ubuntu.
la source
J'ai eu une situation similaire, mais dans mon cas, le lien symbolique doit pointer vers un chemin relatif, j'ai donc écrit ce script python pour faire l'affaire:
Pour chaque ligne d'entrée (qui est une liste de fichiers), le script fractionne la liste de fichiers (séparés par des espaces), obtient le chemin relatif de chaque fichier au premier, puis crée le lien symbolique.
la source
Ainsi, la réponse donnée par arnefm (qui a été copiée partout sur Internet) ne traite pas des espaces dans les noms de fichiers. J'ai écrit un script qui traite des espaces dans les fichiers.
Ce que cela fait, c'est de trouver des dupes et de les écrire PIPE séparés dans un fichier nommé 'files'.
Ensuite, il lit le fichier, ligne par ligne, dans un tableau, et chaque élément du tableau est délimité par le PIPE.
Il itère ensuite sur tous les éléments non premiers du tableau, en remplaçant le fichier par un lien symbolique vers le premier élément.
Le fichier externe («fichiers») pourrait être supprimé, si la commande fdupes est exécutée dans un sous-shell, qui est lu directement par le temps, mais cette façon semble plus claire.
la source
Quelques mises en garde à l'avant:
fdupes -1r common/base/dir | while read -r -a line ; do ln -sf $(realpath --relative-to ${line[1]} ${line[0]}) ${line[1]}; done
Si plus de 2 fichiers sont en double (par exemple, file1 file2 file3), nous devons créer un lien symbolique pour chaque paire - traiter file1, file2 et file1, file3 comme 2 cas distincts:
Le dépenser pour gérer automatiquement un nombre arbitraire de doublons par ligne demandera un peu plus d'efforts.
Une autre approche serait de créer d'abord des liens symboliques vers des chemins absolus, puis de les convertir:
Ceci est basé sur la réponse de @Gilles: /unix//a/100955/77319
la source