Найти файл, когда вы знаете его контрольную сумму?

30

У меня md5sumесть файл, и я не знаю, где он находится в моей системе. Есть ли простой способ findопределить файл на основе его md5? Или мне нужно разработать небольшой скрипт?

Я работаю над AIX 6 без инструментов GNU.

Kiwy
источник
4
Не сузит ли поиск поиск до файлов того же размера, чем вычисление md5, быстрее?
RJ-
@ RJ - да, может быть, но в этом случае это также позволяет мне проверить, является ли файл правильным и был ли передан правильно.
Kiwy

Ответы:

34

Использование find:

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

Если вы выполняете поиск, /вы можете исключить /procи /sysувидеть следующий findпример команды:

Также я провел некоторое тестирование, findзанимая больше времени и меньше ресурсов процессора и оперативной памяти, где сценарий ruby ​​требует меньше времени, но больше ресурсов процессора и оперативной памяти.

Результат испытаний

найти

[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

Найти с -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
Рахул Патил
источник
Вы хотите позвонить -pruneв /sys/ /procвместо того , чтобы спуститься в них и исключить файлы с -path. Вы должны предпочесть !более -notпортативность.
Стефан Шазелас
Сэр, я обновился с -prune, один раз проверьте, все ли в порядке.
Рахул Патил
Вы также хотите, /devконечно, исключить .
Саймон Рихтер
12

Скрипт Решение

#!/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, основанное на вероятности, которое работает быстрее

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

Результат испытаний

[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
Рахул Патил
источник
что бы вы порекомендовали?
Kiwy
@Kiwy Я не рекомендую, просто для практики
Рахул Патил
@Kiwy однажды посмотрите на результат теста и сообщите мне, а также проведите некоторое тестирование с вашей стороны и покажите нам результат. Было бы здорово увидеть результат в AIX. : D
Рахул Патил
Моя главная проблема с вашим скриптом в том, что ему нужен ruby, и он не установлен в моей Системе, и я не являюсь администратором. но я
проведу
Кажется, быстрее, чем найти в конце ^^. может быть, вы могли бы поместить md5sum в поток, чтобы вы могли вычислить 5 md5sum одновременно, это также сэкономило бы немного времени
Kiwy
7

Если вы все-таки решили установить gnu find (и поскольку вы указали интерес к одному из ваших комментариев), вы можете попробовать что-то вроде:

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

и checkmd5сравнить md5sum файла, который он получает в качестве аргумента, сравнить со вторым аргументом и вывести имя, если оно совпадает, и выйти с 1 (вместо 0 в противном случае). -quitБудет иметь findостановку , когда он будет найден.

checkmd5 (не проверено):

#!/bin/bash

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

if [ $md == $2 ] ; then
  echo $1
  exit 1
fi
exit 0
Энтон
источник
Ням No package checkmd5 available, пожалуйста, укажите, какой пакет должен быть установленcheckmd5
Рахул Патил
Мне очень нравится это решение, я не понимаю, checkmd5но мне нравится, как вы это делаете
Kiwy
Добавлен скрипт @kiwy.
Anthon
@RahulPatil это в дистрибутиве DIY ;-)
Anthon
@kiwy Извините, возможно, принял ваше редактирование -type f, но он восстановил мой, который echo $1я уже вставил
Anthon