Trouver des fichiers en double

91

Est-il possible de trouver sur mon disque des fichiers en double identiques, mais ayant des noms de fichiers différents?

étudiant
la source
3
Notez que toute méthode possible pour ce faire devra invariablement comparer chaque fichier de votre système à tous les autres fichiers . Cela va donc prendre beaucoup de temps, même en prenant des raccourcis.
Shadur
4
@Shadur si l'on est d'accord avec les sommes de contrôle, cela revient à comparer uniquement les hachages - qui sur la plupart des systèmes sont de l'ordre de 10 ^ (5 + -1), généralement <64 octets. Bien sûr, vous devez lire les données au moins une fois. :)
peterph
15
@Shadur Ce n'est pas vrai. Vous pouvez réduire le temps en vérifiant la correspondance des st_sizes, en éliminant ceux qui ne possèdent que la même, puis en calculant uniquement les sommes md5 pour la correspondance des st_sizes.
Chris Down
6
@Shadur même une approche incroyablement stupide interdisant toute opération de hachage pourrait le faire en comparant (n log n) - et non Θ (n²) - en utilisant l'un des algorithmes de tri (basé sur le contenu du fichier).
derobert
1
@ChrisDown Oui, la correspondance de taille serait l'un des raccourcis que j'avais en tête.
Shadur

Réponses:

104

fdupespeut le faire. De man fdupes:

Recherche le chemin donné pour les fichiers en double. Ces fichiers sont trouvés en comparant les tailles de fichier et les signatures MD5, suivies d'une comparaison octet par octet.

Dans Debian ou Ubuntu, vous pouvez l’installer avec apt-get install fdupes. Dans Fedora / Red Hat / CentOS, vous pouvez l’installer avec yum install fdupes. Arch Linux , vous pouvez utiliser pacman -S fdupes, et sur Gentoo, emerge fdupes.

Pour exécuter une vérification descendant de la racine de votre système de fichiers, ce qui prendra probablement beaucoup de temps et de mémoire, utilisez quelque chose comme fdupes -r /.

Comme demandé dans les commentaires, vous pouvez obtenir les doublons les plus volumineux en procédant comme suit:

fdupes -r . | {
    while IFS= read -r file; do
        [[ $file ]] && du "$file"
    done
} | sort -n

Cela se brisera si vos noms de fichiers contiennent des nouvelles lignes.

Chris Down
la source
Merci. Comment puis-je filtrer la plus grande dupe? Comment puis-je rendre les tailles lisibles par l'homme?
étudiant
@student: utilisez quelque chose le long de la ligne (assurez-vous que fdupes ne sort que les noms de fichiers sans information supplémentaire, ou ne coupe pas ou ne garde que ça): fdupes ....... | xargs ls -alhd | egrep 'M |G 'garder les fichiers au format lisible par Human et seulement ceux dont la taille est en mégaoctets ou en gigaoctets. Modifiez la commande en fonction des résultats réels.
Olivier Dulac
2
@OlivierDulac Vous ne devriez jamais analyser ls . En règle générale, c'est pire que votre cas d'utilisation, mais même dans ce cas, vous risquez des faux positifs.
Chris Down
@student - Une fois que vous avez les noms de fichiers, dirigez-vous duvers sortvous le diront.
Chris Down
@ChrisDown: il est vrai que c'est une mauvaise habitude et peut donner de faux positifs. Mais dans ce cas (utilisation interactive, et pour l'affichage uniquement, pas de "rm" ou quoi que ce soit du genre qui s'appuie directement dessus), tout va bien et rapidement ^^. J'adore les pages auxquelles vous vous connectez, d'ailleurs (depuis quelques mois, et pleines de nombreuses informations utiles)
Olivier Dulac
27

Un autre bon outil est fslint:

fslint est un ensemble d'outils permettant de rechercher divers problèmes liés aux systèmes de fichiers, notamment les fichiers en double, les noms de fichiers problématiques, etc.

Des outils de ligne de commande individuels sont disponibles en plus de l'interface graphique. Pour y accéder, vous pouvez modifier ou ajouter à $ PATH le répertoire / usr / share / fslint / fslint lors d'une installation standard. Chacune de ces commandes de ce répertoire a une option --help qui détaille ses paramètres.

   findup - find DUPlicate files

Sur les systèmes basés sur Debian, vous pouvez l’installer avec:

sudo apt-get install fslint

Vous pouvez également le faire manuellement si vous ne voulez pas ou ne pouvez pas installer d'outils tiers. La plupart des programmes fonctionnent en calculant les sommes de contrôle des fichiers . Les fichiers avec le même md5sum contiennent presque certainement exactement les mêmes données. Donc, vous pourriez faire quelque chose comme ça:

find / -type f -exec md5sum {} \; > md5sums
gawk '{print $1}' md5sums | sort | uniq -d > dupes
while read d; do echo "---"; grep $d md5sums | cut -d ' ' -f 2-; done < dupes 

Exemple de sortie (les noms de fichier dans cet exemple sont les mêmes, mais cela fonctionnera également s'ils sont différents):

$ while read d; do echo "---"; grep $d md5sums | cut -d ' ' -f 2-; done < dupes 
---
 /usr/src/linux-headers-3.2.0-3-common/include/linux/if_bonding.h
 /usr/src/linux-headers-3.2.0-4-common/include/linux/if_bonding.h
---
 /usr/src/linux-headers-3.2.0-3-common/include/linux/route.h
 /usr/src/linux-headers-3.2.0-4-common/include/linux/route.h
---
 /usr/src/linux-headers-3.2.0-3-common/include/drm/Kbuild
 /usr/src/linux-headers-3.2.0-4-common/include/drm/Kbuild
---

Ce sera beaucoup plus lent que les outils dédiés déjà mentionnés, mais cela fonctionnera.

terdon
la source
4
Il serait beaucoup, beaucoup plus rapide de trouver tous les fichiers de la même taille qu’un autre fichier st_size, en éliminant ceux n’ayant qu’un seul fichier de cette taille, puis en calculant les sommes md5 uniquement entre fichiers ayant le même st_size.
Chris Down
@ChrisDown ouais, je voulais juste garder les choses simples. Ce que vous proposez accélérera grandement les choses, bien sûr. C'est pourquoi j'ai l'avertissement à propos de la lenteur à la fin de ma réponse.
terdon
Il peut être exécuté sur macOS, mais vous devez le remplacer md5sum {}par md5 -q {}et gawk '{print $1}'aveccat
Finesse
8

Réponse courte: oui.

Version plus longue: jetez un coup d’œil à l’ entrée Wikipédia fdupes , elle contient une liste assez intéressante de solutions toutes faites. Bien sûr , vous pouvez écrire votre propre, ce n'est pas que difficile - les programmes de hachage comme diff, sha*sum, find, sortet uniqdevrait faire le travail. Vous pouvez même le mettre sur une seule ligne, et ce sera toujours compréhensible.

Peterph
la source
6

Si vous pensez qu'une fonction de hachage (ici MD5) est sans collision sur votre domaine:

find $target -type f -exec md5sum '{}' + | sort | uniq --all-repeated --check-chars=32 \
 | cut --characters=35-

Vous voulez des noms de fichiers identiques groupés? Ecrivez un script simple not_uniq.shpour formater la sortie:

#!/bin/bash

last_checksum=0
while read line; do
    checksum=${line:0:32}
    filename=${line:34}
    if [ $checksum == $last_checksum ]; then
        if [ ${last_filename:-0} != '0' ]; then
            echo $last_filename
            unset last_filename
        fi
        echo $filename
    else
        if [ ${last_filename:-0} == '0' ]; then
            echo "======="
        fi
        last_filename=$filename
    fi

    last_checksum=$checksum
done

Puis changez la findcommande pour utiliser votre script:

chmod +x not_uniq.sh
find $target -type f -exec md5sum '{}' + | sort | not_uniq.sh

C'est une idée de base. Vous devriez probablement changer findsi vos noms de fichiers contiennent des caractères. (par exemple l'espace)

xin
la source
6

J'ai pensé à ajouter un fork amélioré récent de fdupes, jdupes , qui s'annonce plus rapide et plus riche en fonctionnalités que fdupes (par exemple, le filtre de taille):

jdupes . -rS -X size-:50m > myjdups.txt

Cela recherchera de manière récursive les fichiers dupliqués de plus de 50 Mo dans le répertoire actuel et affichera la liste résultante dans myjdups.txt.

Remarque, la sortie n'est pas triée par taille et, comme elle ne semble pas être intégrée, j'ai adapté la réponse @Chris_Down ci-dessus pour y parvenir:

jdupes -r . -X size-:50m | {
    while IFS= read -r file; do
        [[ $file ]] && du "$file"
    done
} | sort -n > myjdups_sorted.txt
Sebastian Müller
la source
Remarque: la dernière version de jdupes prend en charge les fichiers correspondants avec un hachage partiel au lieu d’attendre que tout soit haché. Très utile. (Vous devez cloner l'archive git pour l'obtenir.) Voici l'option que j'utilise actuellement: jdupes -r -T -T --exclude = taille-: 50m --nohidden
SurpriseDog
2

Wikipedia avait un article ( http://en.wikipedia.org/wiki/List_of_duplicate_file_finders ), avec une liste des logiciels open source disponibles pour cette tâche, mais ils ont maintenant été supprimés .

J'ajouterai que la version graphique de fslint est très intéressante, ce qui permet d'utiliser un masque pour sélectionner les fichiers à supprimer. Très utile pour nettoyer les photos dupliquées.

Sous Linux, vous pouvez utiliser:

- FSLint: http://www.pixelbeat.org/fslint/

- FDupes: https://en.wikipedia.org/wiki/Fdupes

- DupeGuru: https://www.hardcoded.net/dupeguru/

Les 2 derniers travaux sur de nombreux systèmes (Windows, Mac et Linux) Je n’ai pas vérifié FSLint

MordicusEtCubitus
la source
5
Il est préférable de fournir des informations réelles ici et pas seulement un lien, le lien peut changer et la réponse n'a alors plus aucune valeur
Anthon
2
La page Wikipedia est vide.
ihor_dvoretskyi
oui, il a été nettoyé, quel dommage shake ...
MordicusEtCubitus
Je l'ai édité avec ces 3 outils
MordicusEtCubitus
0

Voici mon point de vue sur cela:

find -type f -size +3M -print0 | while IFS= read -r -d '' i; do
  echo -n '.'
  if grep -q "$i" md5-partial.txt; then echo -e "\n$i  ---- Already counted, skipping."; continue; fi
  MD5=`dd bs=1M count=1 if="$i" status=noxfer | md5sum`
  MD5=`echo $MD5 | cut -d' ' -f1`
  if grep "$MD5" md5-partial.txt; then echo "\n$i  ----   Possible duplicate"; fi
  echo $MD5 $i >> md5-partial.txt
done

C'est différent en ce sens qu'il ne hache que jusqu'à 1 Mo du fichier.
Cela a quelques problèmes / fonctionnalités:

  • Il se peut qu’il y ait une différence après les premiers 1 Mo, le résultat est donc plutôt un candidat à vérifier. Je pourrais résoudre ce problème plus tard.
  • Vérifier d'abord par la taille du fichier pourrait accélérer le processus.
  • Prend uniquement les fichiers de plus de 3 Mo.

Je l'utilise pour comparer des clips vidéo, donc cela me suffit.

Ondra Žižka
la source