Tìm một tập tin khi bạn biết tổng kiểm tra của nó?


29

Tôi có md5summột tập tin và tôi không biết nó ở đâu trên hệ thống của tôi. Có bất kỳ tùy chọn dễ dàng findđể xác định một tập tin dựa trên nó md5? Hay tôi cần phát triển một kịch bản nhỏ?

Tôi đang làm việc trên AIX 6 mà không có các công cụ GNU.


4
Sẽ không thu hẹp tìm kiếm vào kích thước tệp có cùng kích thước sau đó tính toán md5 sẽ nhanh hơn?
RJ-

@ RJ- có thể nhưng trong trường hợp này nó cũng cho phép tôi kiểm tra xem tập tin có đúng không và đã được chuyển đúng chưa.
Kiwy

Câu trả lời:


33

Sử dụng find:

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

Nếu bạn tìm kiếm thông qua /thì bạn có thể loại trừ /proc/sysxem findví dụ lệnh sau :

Ngoài ra tôi đã thực hiện một số thử nghiệm, findmất nhiều thời gian hơn và ít CPU và RAM hơn trong đó tập lệnh ruby ​​mất ít thời gian hơn nhưng nhiều CPU và RAM hơn

Kết quả kiểm tra

Tìm thấy

[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

Tìm với -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

Tập lệnh Ruby

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

real    1m3.065s
user    0m2.231s
sys     0m20.706s

Bạn muốn gọi -prunevào /sys/ /procthay vì giảm dần trong họ và loại trừ các file với -path. Bạn nên thích !hơn -notcho tính di động.
Stéphane Chazelas

Thưa ông, tôi đã cập nhật -prune, một lần kiểm tra xem nó có ổn không.
Rahul Patil

Bạn cũng muốn loại trừ /devchắc chắn.
Simon Richter

12

Giải pháp kịch bản

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

Giải pháp Bash Script dựa trên xác suất hoạt động nhanh hơn

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

Kết quả kiểm tra

[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

bạn muốn giới thiệu cái gì
Kiwy

@Kiwy Tôi không khuyên bạn, Chỉ để thực hành
Rahul Patil

@Kiwy một lần nhìn vào kết quả kiểm tra và cho tôi biết và cũng thực hiện một số thử nghiệm từ phía bạn và cho chúng tôi thấy kết quả, Thật tuyệt khi thấy kết quả trên AIX. : D
Rahul Patil

Vấn đề chính của tôi với kịch bản của bạn là nó cần ruby ​​và nó không được cài đặt trên Hệ thống của tôi và tôi không phải là quản trị viên. nhưng tôi sẽ chạy thử nghiệm tối nay nếu tôi tìm thấy chút thời gian
Kiwy

Có vẻ như nhanh hơn tìm thấy cuối cùng ^^. có lẽ bạn có thể đặt md5sum vào một chủ đề để bạn có thể tính toán 5 md5sum cùng một lúc nó cũng có thể tiết kiệm một chút thời gian
Kiwy

7

Nếu bạn quyết định cài đặt gnu find anyway (và vì bạn đã thể hiện sự quan tâm đến một trong những bình luận của mình), bạn có thể thử một cái gì đó như:

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

và đã checkmd5so sánh md5sum của tệp mà nó nhận làm đối số so với đối số thứ hai và in tên nếu nó khớp và thoát với 1 (thay vì 0 nếu không). Các -quitsẽ phải finddừng lại một khi nó được tìm thấy.

checkmd5 (không được kiểm tra):

#!/bin/bash

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

if [ $md == $2 ] ; then
  echo $1
  exit 1
fi
exit 0

Yum No package checkmd5 available, vui lòng bao gồm gói nào cần được cài đặt chocheckmd5
Rahul Patil

Tôi thích giải pháp này quá tệ Tôi không nhận được checkmd5nhưng tôi thích cách bạn thực hiện
Kiwy 11/03/2016

@kiwy script được thêm vào.
Anthon

@RahulPatil nó nằm trong bản phân phối DIY ;-)
Anthon

@kiwy Xin lỗi có thể đã chấp nhận chỉnh sửa của bạn -type f, nhưng nó đã xóa bỏ tôi echo $1đã đưa vào
Anthon
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.