Trouver un fichier lorsque vous connaissez sa somme de contrôle?

30

J'ai le md5sumfichier et je ne sais pas où il se trouve sur mon système. Existe-t-il une option simple findpour identifier un fichier en fonction de son md5? Ou dois-je développer un petit script?

Je travaille sur AIX 6 sans les outils GNU.

Kiwy
la source
4
Ne serait-il pas plus rapide de restreindre la recherche à des tailles de fichier de même taille, puis de calculer le md5?
RJ-
@ RJ- oui peut-être mais dans ce cas cela me permet également de vérifier si le fichier est correct et a été transféré correctement.
Kiwy

Réponses:

34

En utilisant find:

find /tmp/ -type f -exec md5sum {} + | grep '^file_md5sum_to_match'

Si vous recherchez, /vous pouvez exclure /procet /sysvoir l' findexemple de commande suivant :

De plus, j'avais fait des tests, findpris plus de temps et moins de CPU et de RAM où le script ruby ​​prend moins de temps mais plus de CPU et de RAM

Résultat du test

Trouver

[root@dc1 ~]# time find / -type f -not -path "/proc/*" -not -path "/sys/*" -exec md5sum {} + | grep '^304a5fa2727ff9e6e101696a16cb0fc5'
304a5fa2727ff9e6e101696a16cb0fc5  /tmp/file1


real    6m20.113s
user    0m5.469s
sys     0m24.964s

Trouvez avec -prune

[root@dc1 ~]# time find / \( -path /proc -o -path /sys \) -prune -o -type f -exec md5sum {} + | grep '^304a5fa2727ff9e6e101696a16cb0fc5'
304a5fa2727ff9e6e101696a16cb0fc5  /tmp/file1

real    6m45.539s
user    0m5.758s
sys     0m25.107s

Ruby Script

[root@dc1 ~]# time ruby findm.rb
File Found at: /tmp/file1

real    1m3.065s
user    0m2.231s
sys     0m20.706s
Rahul Patil
la source
Vous voulez appeler -prunesur /sys/ /procau lieu de descendre en eux et exclure les fichiers avec -path. Vous devriez préférer !la -notportabilité.
Stéphane Chazelas
Monsieur, j'ai mis à jour avec -prune, une fois vérifier s'il est OK.
Rahul Patil
Vous voulez également exclure /devcertainement.
Simon Richter
12

Solution de script

#!/usr/bin/ruby -w

require 'find'
require 'digest/md5'

file_md5sum_to_match = [ '304a5fa2727ff9e6e101696a16cb0fc5',
                         '0ce6742445e7f4eae3d32b35159af982' ]

Find.find('/') do |f|
  next if /(^\.|^\/proc|^\/sys)/.match(f) # skip
  next unless File.file?(f)
  begin
        md5sum = Digest::MD5.hexdigest(File.read(f))
  rescue
        puts "Error reading #{f} --- MD5 hash not computed."
  end
  if file_md5sum_to_match.include?(md5sum)
       puts "File Found at: #{f}"
       file_md5sum_to_match.delete(md5sum)
  end
  file_md5sum_to_match.empty? && exit # if array empty then exit

end

Solution Bash Script basée sur la probabilité qui fonctionne plus rapidement

#!/bin/bash
[[ -z $1 ]] && read -p "Enter MD5SUM to search file: " md5 || md5=$1

check_in=( '/home' '/opt' '/tmp' '/etc' '/var' '/usr'  )
last_find_cmd="find / \\( -path /proc -o -path /sys ${check_in[@]/\//-o -path /} \\) -prune -o -type f -exec md5sum {} +"
last_element=${#check_in}
echo "Please wait... searching for file"
for d in ${!check_in[@]}
do

        [[ $d == $last_element ]] && eval $last_find_cmd | grep "^${md5}" && exit

        find ${check_in[$d]} -type f -exec md5sum {} + | grep "^${md5}" && exit


done

Résultat du test

[root@dc1 /]# time bash find.sh 304a5fa2727ff9e6e101696a16cb0fc5
Please wait... searching for file
304a5fa2727ff9e6e101696a16cb0fc5  /var/log/file1

real    0m21.067s
user    0m1.947s
sys     0m2.594s
Rahul Patil
la source
que recommanderiez-vous?
Kiwy
@Kiwy, je ne recommande pas, juste pour la pratique
Rahul Patil
@Kiwy regarde une fois le résultat du test et faites-le moi savoir et faites également des tests de votre côté et montrez-nous le résultat, ce serait formidable de voir le résultat sur AIX. : D
Rahul Patil
Mon principal problème avec votre script est qu'il a besoin de ruby ​​et qu'il n'est pas installé sur mon système et que je ne suis pas administrateur. mais je vais faire un test ce soir si je trouve du temps
Kiwy
Cela semble plus rapide que de trouver à la fin ^^. vous pourriez peut-être mettre le md5sum dans un thread afin que vous puissiez calculer 5 md5sum en même temps, cela pourrait également gagner un peu de temps
Kiwy
7

Si vous décidez d'installer gnu find de toute façon (et puisque vous avez indiqué votre intérêt pour l'un de vos commentaires), vous pouvez essayer quelque chose comme:

find / -type f \( -exec checkmd5 {} YOURMD5SUM \; -o -quit \) 

et checkmd5comparer la somme md5 du fichier obtenu en tant qu'argument au deuxième argument et afficher le nom s'il correspond et quitter avec 1 (au lieu de 0 sinon). Le -quitsera findarrêté une fois qu'il sera trouvé.

checkmd5 (pas testé):

#!/bin/bash

md=$(md5sum $1 |  cut -d' ' -f1)

if [ $md == $2 ] ; then
  echo $1
  exit 1
fi
exit 0
Anthon
la source
Miam No package checkmd5 available, veuillez indiquer pour quel paquet doit être installécheckmd5
Rahul Patil
J'aime trop cette solution, je ne la trouve pas, checkmd5mais j'aime la façon dont vous la faites
Kiwy
Ajout du script @kiwy.
Anthon
@RahulPatil c'est dans la distribution DIY ;-)
Anthon
@kiwy Désolé, vous auriez pu accepter votre modification -type f, mais elle a été annulée, je l' echo $1avais déjà insérée
Anthon