Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I have the md5sum of a file and I don't know where it is on my system. Is there any easy option of find to identify a file based on its md5? Or do I need to develop a small script ?

I'm working on AIX 6 without the GNU tools.

share|improve this question
3  
Wouldn't narrowing the search to file sizes of the same size then computing the md5 be faster? –  b70568b5 Mar 11 at 20:49
    
@RJ- yes maybe but in this case it also allow me to check if the file is the correct one and has been transfer correctly. –  Kiwy Mar 12 at 8:28

3 Answers 3

up vote 19 down vote accepted

Using find:

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

If you searching through / then you can exclude /proc and /sys see following find command example :

Also I had done some testing, find take more time and less CPU and RAM where ruby script is taking less time but more CPU and RAM

Test Result

Find

[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

Find with -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
share|improve this answer
    
You want to call -prune on /sys//proc instead of descending in them and exclude files with -path. You should prefer ! over -not for portability. –  Stéphane Chazelas Mar 11 at 11:53
    
Sir I've updated with -prune, once check if it is OK. –  Rahul Patil Mar 11 at 12:34
    
You also want to exclude /dev certainly. –  Simon Richter Mar 12 at 10:21

Script Solution

#!/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

Bash Script solution based on probability which works faster

#!/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

Test Result

[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
share|improve this answer
    
which would you recommend ? –  Kiwy Mar 11 at 10:21
    
@Kiwy I'm not recommend, Just for practice –  Rahul Patil Mar 11 at 10:22
    
@Kiwy once look at test result and let me know and also do some testing from your side and show us the result, It would be great to see result on AIX. :D –  Rahul Patil Mar 11 at 10:53
    
My main issue with your script is that it needs ruby and it's not install on my System, and I'm not admin. but I will run some test tonight if I find some time –  Kiwy Mar 11 at 10:54
    
@Kiwy thanks.. ... ... –  Rahul Patil Mar 11 at 10:55

If you decide to install gnu find anyway (and since you indicated interest in one of your comments), you can try something like:

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

and have checkmd5 compare the md5sum of the file it gets as argument compare to the second argument and print the name if it matches and exit with 1 (instead of 0 otherwise). The -quit will have find stop once it is found.

checkmd5 (not tested):

#!/bin/bash

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

if [ $md == $2 ] ; then
  echo $1
  exit 1
fi
exit 0
share|improve this answer
    
Yum No package checkmd5 available, please include which package need to be install for checkmd5 –  Rahul Patil Mar 11 at 10:59
    
I like this solution too bad I don't get checkmd5 but I like the way you do it –  Kiwy Mar 11 at 11:00
    
@kiwy script added. –  Anthon Mar 11 at 11:06
    
@RahulPatil it is in the DIY distribution ;-) –  Anthon Mar 11 at 11:06
    
@kiwy Sorry could have accepted your edit for -type f, but it undeleted my echo $1 I already had put in –  Anthon Mar 11 at 11:15

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.