web-dev-qa-db-fra.com

Existe-t-il un moyen simple de remplacer les fichiers en double par des liens physiques?

Je cherche un moyen simple (une commande ou une série de commandes, impliquant probablement find) pour trouver des fichiers en double dans deux répertoires et remplacer les fichiers dans un répertoire par des liens physiques des fichiers dans l'autre répertoire.

Voici la situation: il s'agit d'un serveur de fichiers sur lequel plusieurs personnes stockent des fichiers audio, chaque utilisateur ayant son propre dossier. Parfois, plusieurs personnes ont des copies des mêmes fichiers audio. Pour l'instant, ce sont des doublons. Je voudrais que ce soit des liens durs, pour économiser de l'espace sur le disque dur.

146
Josh

Il y a un script Perl sur http://cpansearch.Perl.org/src/ANDK/Perl-Repository-APC-2.002/eg/trimtrees.pl qui fait exactement ce que vous voulez:

Parcourez tous les répertoires nommés sur la ligne de commande, calculez les sommes de contrôle MD5 et recherchez des fichiers avec des MD5 identiques. S'ils sont égaux, faites une comparaison réelle s'ils sont vraiment égaux, remplacez le deuxième des deux fichiers par un lien dur vers le premier.

42
fschmitt

rdfind fait exactement ce que vous demandez (et dans l'ordre johny pourquoi listes). Permet de supprimer les doublons, de les remplacer par des liens logiciels ou matériels. Combiné avec symlinks, vous pouvez également rendre le lien symbolique absolu ou relatif. Vous pouvez même choisir l'algorithme de somme de contrôle (md5 ou sha1).

Comme il est compilé, il est plus rapide que la plupart des solutions scriptées: time sur un dossier 15 GiB avec 2600 fichiers sur mon Mac Mini à partir de 2009 renvoie ce

9.99s user 3.61s system 66% cpu 20.543 total

(en utilisant md5).

Disponible dans la plupart des gestionnaires de packages (par exemple MacPorts pour Mac OS X).

98
d-b

Utilisez l'outil fdupes:

fdupes -r /path/to/folder vous donne une liste de doublons dans le répertoire (-r le rend récursif). La sortie ressemble à ceci:


filename1
nom_fichier2

filename3
nom_fichier4
nomfichier5


avec filename1 et filename2 étant identiques et filename3, filename4 et filename5 étant également identiques.

51
tante
24
waltinator

C'est l'une des fonctions fournies par "fslint" - http://en.flossmanuals.net/FSlint/Introduction

Cliquez sur le bouton "Fusionner":

Screenshot

18
LJ Wobker

Étant donné que votre objectif principal est d'économiser de l'espace disque, il existe une autre solution: la déduplication (et probablement la compression) au niveau du système de fichiers. Par rapport à la solution de liaison matérielle, elle n'a pas le problème d'affecter par inadvertance d'autres fichiers liés.

ZFS a dédoublé (niveau bloc, pas niveau fichier) depuis la version 23 du pool et la compression depuis longtemps. Si vous utilisez Linux, vous pouvez essayer zfs-Fuse , ou si vous utilisez BSD, il est nativement pris en charge.

14
Wei-Yin

Sur Linux moderne ces jours-ci, il y a https://github.com/g2p/bedup qui se dédoublonne sur un système de fichiers btrfs, mais 1) sans autant de frais généraux de numérisation, 2) les fichiers peuvent diverger facilement encore une fois par la suite.

7
Matthew Bloch
aptitude show hardlink

Description: Hardlinks plusieurs copies du même fichier Hardlink est un outil qui détecte plusieurs copies du même fichier et les remplace par des hardlinks.

L'idée est tirée de http://code.google.com/p/hardlinkpy/ , mais le code a été écrit à partir de zéro et autorisé sous le MIT Page d'accueil: http://jak-linux.org/projects/hardlink/

6
Julien Palard

Pour trouver des fichiers en double, vous pouvez utiliser duff.

Duff est un utilitaire de ligne de commande Unix pour trouver rapidement des doublons dans un ensemble de fichiers donné.

Exécutez simplement:

duff -r target-folder

Pour créer automatiquement des liens physiques vers ces fichiers, vous devrez analyser la sortie de duff avec bash ou un autre script Langue.

6
Stefan

J'ai utilisé la plupart des outils de hardlinking pour Linux mentionnés ici. Moi aussi, je suis coincé avec ext4 fs, sur Ubuntu, et j'ai utilisé ses cp -l et - s pour hard/softlinking. Mais récemment, j'ai remarqué la copie légère dans la page de manuel cp, ce qui impliquerait de ménager l'espace disque redondant jusqu'à un côté est modifié:

   --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 a été mentionné dans un commentaire mais mérite sa propre réponse, car il est probablement disponible dans la plupart des distributions et fonctionne assez rapidement (il vient de libérer 2,7 Go d'une partition à 98% de 158 Go (lecteur SSD) dans environ une minute) :

jdupes -rL /foo/bar

Il me semble que la première vérification du nom de fichier pourrait accélérer les choses. Si deux fichiers n'ont pas le même nom de fichier, dans de nombreux cas, je ne les considérerais pas comme des doublons. Semble que la méthode la plus rapide serait de comparer, dans l'ordre:

  • nom de fichier
  • taille
  • somme de contrôle md5
  • contenu en octets

Existe-t-il des méthodes? Regardez duff, fdupes, rmlint, fslint, etc.

La méthode suivante a été votée en tête commandlinefu.com : Rechercher les fichiers en double (en fonction de la taille d'abord, puis du hachage MD5)

La comparaison des noms de fichiers peut-elle être ajoutée dans un premier temps, la taille dans un deuxième temps?

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

Comme je ne suis pas fan de Perl, voici une version 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

Cela trouve tous les fichiers avec la même somme de contrôle (qu'ils soient gros, petits ou déjà des liens durs), et les lie durs ensemble.

Cela peut être grandement optimisé pour les exécutions répétées avec des indicateurs de recherche supplémentaires (par exemple, la taille) et un cache de fichiers (vous n'avez donc pas à refaire les sommes de contrôle à chaque fois). Si quelqu'un s'intéresse à la version plus intelligente et plus longue, je peux la poster.

REMARQUE: Comme cela a été mentionné précédemment, les liens physiques fonctionnent tant que les fichiers n'ont jamais besoin d'être modifiés ou d'être déplacés d'un système de fichiers à l'autre.

3
seren

Si vous souhaitez remplacer les doublons par des liens durs sur mac ou tout système UNIX, vous pouvez essayer SmartDupe http://sourceforge.net/projects/smartdupe/ je le développe

1
islam

J'ai créé un script Perl qui fait quelque chose de similaire à ce dont vous parlez:

http://Pastebin.com/U7mFHZU7

Fondamentalement, il traverse simplement un répertoire, calculant la somme SHA1 des fichiers qu'il contient, le hachant et reliant les correspondances. C'est utile à de très nombreuses reprises.

1
amphetamachine

Les applications FSLint ( http://www.pixelbeat.org/fslint/ ) peuvent trouver tous les fichiers égaux dans n'importe quel dossier (par contenu) et créer des liens physiques. Essaie!

Jorge Sampaio

1

Les liens matériels ne sont peut-être pas la meilleure idée; si un utilisateur modifie le fichier, cela affecte les deux. Cependant, la suppression d'un lien dur ne supprime pas les deux fichiers. De plus, je ne suis pas tout à fait sûr que les liens durs occupent la même quantité d'espace (sur le disque dur, pas le système d'exploitation) que plusieurs copies du même fichier; selon Windows (avec l'extension Link Shell), ils le font. Certes, c'est Windows, pas Unix ...

Ma solution serait de créer un fichier "commun" dans un dossier caché et de remplacer les doublons réels par des liens symboliques ... puis, les liens symboliques seraient incorporés avec des métadonnées ou des flux de fichiers alternatifs qui n'enregistrent cependant que les deux "fichiers" sont différents les uns des autres, comme si une personne veut changer le nom de fichier ou ajouter une pochette d'album personnalisée ou quelque chose d'autre comme ça; il peut même être utile en dehors des applications de base de données, comme installer plusieurs versions du même jeu ou logiciel et les tester indépendamment, même avec les plus petites différences.

0
Amaroq Starwind

Si vous allez créer des liens physiques, faites attention aux droits sur ce fichier. Remarquez que le propriétaire, le groupe, le mode, les attributs étendus, l'heure et l'ACL (si vous l'utilisez) sont stockés dans INODE. Seuls les noms de fichiers sont différents car ils sont stockés dans la structure de répertoires et d'autres pointent vers les propriétés INODE. Cette cause, tous les noms de fichiers liés au même inode, ont les mêmes droits d'accès. Vous devez empêcher la modification de ce fichier, car tout utilisateur peut endommager le fichier à un autre. C'est simple. Il suffit que tout utilisateur mette un autre fichier du même nom. Le numéro d'inode est ensuite enregistré et le contenu du fichier d'origine est détruit (remplacé) pour tous les noms liés en dur.

La meilleure façon est la déduplication sur la couche du système de fichiers. Vous pouvez utiliser BTRFS (très populaire la dernière fois), OCFS ou comme ça. Regardez la page: https://en.wikipedia.org/wiki/Comparison_of_file_systems , spécialement dans le tableau Fonctionnalités et déduplication des données de colonne. Vous pouvez cliquer dessus et trier :)

Regardez spécialement le système de fichiers ZFS. Il est disponible en tant que fusible, mais de cette façon, il est très lent. Si vous voulez un support natif, regardez la page http://zfsonlinux.org/ . Ensuite, vous devez patcher le noyau et installer ensuite les outils zfs pour la gestion. Je ne comprends pas, pourquoi Linux ne prend pas en charge les pilotes, c'est la voie pour de nombreux autres systèmes d'exploitation/noyaux.

Les systèmes de fichiers prennent en charge la déduplication de 2 manières, des fichiers dédupliqués ou des blocs. ZFS prend en charge le bloc. Cela signifie que le même contenu qui se répète dans le même fichier peut être dédupliqué. L'autre manière est le moment où les données sont dédupliquées, cela peut être en ligne (zfs) ou hors ligne (btrfs).

Remarquez que la déduplication consomme de la RAM. C'est la raison pour laquelle l'écriture de fichiers sur un volume ZFS monté avec Fuse entraîne une baisse considérable des performances. Ceci est décrit dans la documentation. Mais vous pouvez activer/désactiver la déduplication en ligne sur le volume. Si vous voyez que des données doivent être dédupliquées, il vous suffit d'activer la déduplication, de réécrire certains fichiers dans un fichier temporaire et de les remplacer enfin. après cela, vous pouvez désactiver la déduplication et restaurer toutes les performances. Bien sûr, vous pouvez ajouter au stockage tous les disques de cache. Il peut s'agir de disques à rotation très rapide ou de disques SSD. Bien sûr, cela peut être de très petits disques. Dans le travail réel, cela remplace RAM :)

Sous Linux, vous devez prendre soin de ZFS car tout ne fonctionne pas comme il se doit, spécialement lorsque vous gérez le système de fichiers, faites des instantanés, etc. mais si vous faites la configuration et ne la changez pas, tout fonctionne correctement. Sinon, vous devriez changer linux en opensolaris, il supporte nativement ZFS :) Ce qui est très sympa avec ZFS, cela fonctionne à la fois comme système de fichiers et gestionnaire de volume similaire à LVM. Vous n'en avez pas besoin lorsque vous utilisez ZFS. Consultez la documentation si vous voulez en savoir plus.

Remarquez la différence entre ZFS et BTRFS. ZFS est plus ancien et plus mature, malheureusement uniquement sous Solaris et OpenSolaris (malheureusement étranglé par Oracle). BTRFS est plus jeune, mais la dernière fois très bien pris en charge. Je recommande un noyau frais. ZFS a une déduplication en ligne, qui ralentit les écritures, car tout est calculé en ligne. BTRFS prend en charge la dédupliaction hors ligne. Ensuite, cela économise les performances, mais lorsque l'hôte n'a rien à faire, vous exécutez régulièrement l'outil pour effectuer la déduplication. Et BTRFS est nativement créé sous Linux. Peut-être que c'est mieux FS pour vous :)

0
Znik

Le moyen le plus simple est d'utiliser le programme spécial dupeGuru

dupeGuru Preferences Screenshot

comme documentation dit

Options de suppression

Ces options affectent le mode de suppression des doublons. La plupart du temps, vous n'avez besoin d'activer aucun d'entre eux.

Lier les fichiers supprimés:

Les fichiers supprimés sont remplacés par un lien vers le fichier de référence. Vous avez le choix de le remplacer par un lien symbolique ou un lien dur. ... un lien symbolique est un raccourci vers le chemin du fichier. Si le fichier d'origine est supprimé ou déplacé, le lien est rompu. Un lien physique est un lien vers le fichier lui-même. Ce lien est aussi bon qu'un "vrai" fichier. Ce n'est que lorsque tous les liens physiques vers un fichier sont supprimés que le fichier lui-même est supprimé.

Sous OSX et Linux, cette fonctionnalité est entièrement prise en charge, mais sous Windows, c'est un peu compliqué. Windows XP ne le prend pas en charge, mais Vista et les versions ultérieures le prennent en charge. Cependant, pour que la fonctionnalité fonctionne, dupeGuru doit fonctionner avec des privilèges administratifs.