Question Supprimer les fichiers en double, mais uniquement s'ils se trouvent dans le même dossier?


J'ai lu la FAQ et je sais que cela va bientôt être clos en demandant une recommandation de produit ...

J'ai examiné au moins 40 utilitaires de suppression de "fichiers en double" (Windows, OSX et Linux) et aucun d'entre eux ne possède la fonctionnalité que je recherche.

Je dois le faire maintenant si quelque chose peut le faire ou si je dois écrire mon propre outil pour cela.

Juste une réponse "Oui, ça existe" me conviendrait.
Cela voudrait dire que je n'ai pas cherché assez fort.

Ma fonctionnalité requise: Supprimer les fichiers en double sur une grande structure de dossiers, mais UNIQUEMENT si les doublons résident dans le même dossier.
Par exemple. Disons que j'ai les fichiers A, B et C qui sont identiques. A et C sont dans le même dossier. B est dans un autre dossier. A ou C doit être supprimé (pas de préférence), mais B doit être laissé seul.

Y a-t-il quelque chose là-bas qui peut faire cela?
(De préférence Windows, mais OS-X ou Linux est également correct.)


4
2017-09-05 16:19


origine


Tout d'abord: find -type d pour parcourir tous les dossiers, en utilisant ceci pour -exec une nouvelle recherche avec -maxdepth 1 et -exec pour agir sur tous les fichiers de ce répertoire. Cela semble très inefficace. Avez-vous besoin d'une solution unique ou devez-vous l'exécuter fréquemment? modifier Une seule recherche avec md5hashes stockant tout dans un fichier et agissant sur ce fichier serait plus efficace.) - Hennes
Cette question semble se situer dans le cadre des questions autorisées, à condition de ne pas demander au logiciel de le faire. - Frank
Je suppose que vous voulez que cet outil soit automatisé et capable d'effectuer des opérations par lots? - Ramhound
Je dis que Python a ce qu'il vous faut (principalement parce que je travaille sur un outil similaire). Ce que vous voulez est "relativement" facile avec les modules os, filecmp et shutil. La meilleure partie Python est portable pour ces systèmes. - Doktoro Reichard
@Hennes, Ramhound Il faut que je lance ça toutes les deux semaines sur 15 000 dossiers avec plus de 8 millions de fichiers (et en pleine croissance), attendez-vous à environ 0,1% de doublons. Et une collision par hachage MD5 (aussi improbable soit-elle) n'est pas acceptable, nécessite une comparaison binaire complète. Heureusement, la plupart des fichiers sont relativement petits (80% <1 Mo, 19% <5 Mo, 1% autour de 100 Mo). - Tonny


Réponses:


Vous pouvez utiliser fdupes sans pour autant -r il ne descend donc pas dans les sous-répertoires. Cela imprime une liste de fichiers en double:

find . -type d -exec fdupes -n {} \;

-n ignore les fichiers vides. Ajouter -dN (--delete --noprompt) pour supprimer tout sauf le premier fichier en double.

Vous pouvez installer fdupes sur OS X avec brew install fdupes.


3
2017-09-05 18:27



Si j'ai compris, l'OP devrait alors exécuter cette commande dans tous les sous-répertoires? - Doktoro Reichard
Non, la commande trouve tous les répertoires sous le répertoire en cours de manière récursive puis s'exécute fdupes en eux. - user495470
Une explication légèrement plus longue. find commence à chercher dans le répertoire en cours (marqué avec le .) et trouvera tous les fichiers et répertoires. la -type d L'option limite cela à tous les répertoires. Donc, vous n'avez pas une liste de tous les répertoires. Pour chacun de ceux qui le feront exec le programme fdupes -n avec le nom du répertoire ajouté (c'est-à-dire le {}). - Hennes
J'ai dû installer Homebrew en premier, mais il utilise maintenant -ndN. Courir pendant une heure maintenant. On dirait que ça va prendre environ 5 heures au total, ce qui n’est pas trop mal. (Je cours sous MacPro sur un partage SMB sur le NAS NetApp. Le NAS a un réseau local 10G et le Mac seulement 1G, donc je ne sature pas le NAS. (Peut-être aurait-il utilisé un serveur Linux mais aussi 10G) ... Les autres utilisateurs ne seraient pas trop heureux je pense.) - Tonny


Eh bien comme je l'ai dit, j'ai travaillé sur un script Python qui fait exactement cela.

Je l'ai hébergé à Code Google et je l'ai open-source en tant que GPL v3, donc je suppose que quiconque veut améliorer le programme peut le faire.

Je l'ai aussi débogué un peu (créé des dizaines de fichiers dans Windows, supprimés tous laissant les originaux). Le code est fortement commenté pour informer quiconque de ce que le code fait réellement.

Je l'ai exécuté sur Python 3.3 mais je suppose qu'il devrait fonctionner avec le dernier Python 2.

Oh, et la meilleure partie, cela devrait fonctionner sur tous les OS supportés par Python (Windows, OSX, Linux, ...)


5
2017-09-05 17:34



Personnellement, je ne suis pas familier avec Python (je suis un gars de C / C ++) mais je vais certainement l'examiner. - Tonny
J'étais aussi un C / C ++, mais Python a une politique de "batteries incluses" qui est très attrayante. Si vous êtes familier avec C ++, la syntaxe est légèrement différente mais notez que vous devez vous y mettre. - Doktoro Reichard
Je viens de lire votre commentaire sur la comparaison binaire complète et mis à jour le code en ce qui concerne. - Doktoro Reichard
Même si j'ai déjà utilisé la méthode fdupes mentionnée ci-dessus, je vais certainement regarder dans votre programme Python. Je veux de plus en plus me familiariser avec Python et je trouve toujours plus facile d'apprendre si j'ai des exemples de programmes réels à étudier. Les échantillons dans les livres sont souvent très artificiels et un grand programme est généralement trop complexe. Cela devrait être de taille raisonnable et traiter des problèmes réels. - Tonny


C'est une approche lente mais sûre et très simple qui devrait fonctionner à la fois sur OSX et Linux. Je suppose que vous êtes intéressé par les fichiers en double résidant dans votre $HOME mais vous pouvez changer cela pour répondre à vos besoins.

L'idée est de trouver d'abord une liste de tous les répertoires, puis de comparer les fichiers qu'ils contiennent et de supprimer ceux qui sont identiques. Comme je le disais, cela est très simpliste, il suffit donc de conserver la première des paires de fichiers et de supprimer le reste sans avertissement.

Cela va imprimer les dupes mais ne fera aucun changement à vos fichiers:

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

Celui-ci supprimer silencieusement les fichiers en double, ne l'exécuter que si vous êtes sûr que c'est OK:

find $HOME  -mindepth 1 -type d | 
while read dir; do 
  find $dir -type -f -exec md5sum {} \; | sort > md5sums;
  gawk '{print $1}' md5sums | sort | uniq -d |
  while read d; do grep -w $d md5sums | cut -d ' ' -f 2- | tail -n +2; done |
  | xargs rm ; 
done; rm dupes md5sum 

CAVEATS: Ceci est lent, en fait SLOW, ne donnera pas d'avertissement et supprimera les fichiers en silence. Sur le plan positif, il ne le fera que si ces fichiers se trouvent dans le même répertoire que vous voulez.


1
2017-09-05 17:07