本文提供一個完整的 Ruby 腳本,遞迴走訪指定目錄,計算每個檔案的 MD5 雜湊值並輸出「雜湊值 檔案路徑」格式,適用於檔案完整性驗證、重複檔案偵測、備份校驗等場景。
#!/usr/bin/ruby -w
require 'digest/md5'
if ARGV.empty?
puts "Usage: #$0 "
exit 1
end
dir_name = ARGV.shift
def dir_md5sum(path)
md5s = []
if File.directory?(path)
Dir.foreach(path) do |file|
next if file == '.' || file == '..'
full = File.join(path, file)
if File.directory?(full)
md5s.concat(dir_md5sum(full))
elsif File.file?(full)
begin
md5 = Digest::MD5.hexdigest(File.read(full))
md5s << "#{md5} #{full}"
rescue => e
warn "Error reading #{full}: #{e}"
end
end
end
elsif File.file?(path)
md5 = Digest::MD5.hexdigest(File.read(path))
md5s << "#{md5} #{path}"
else
puts "Invalid path type"
exit 2
end
md5s
end
results = dir_md5sum(dir_name)
results.each { |line| puts line }
# 儲存為 md5sum.rb
ruby md5sum.rb /path/to/directory
# 輸出範例:
# d41d8cd98f00b204e9800998ecf8427e /path/to/empty.txt
# 5d41402abc4b2a76b9719d911017c592 /path/to/hello.txt
rescue 捕獲讀取失敗(權限、損壞、被鎖定),輸出警告不中斷流程。
def file_md5_stream(path, chunk_size = 8192)
digest = Digest::MD5.new
File.open(path, 'rb') do |f|
while chunk = f.read(chunk_size)
digest.update(chunk)
end
end
digest.hexdigest
end
# 在 dir_md5sum 中替換:
# md5 = file_md5_stream(full)
require 'parallel'
files = []
Find.find(dir_name) { |f| files << f if File.file?(f) }
results = Parallel.map(files, in_processes: 4) do |f|
"#{file_md5_stream(f)} #{f}"
end
puts results
輸出格式 MD5_PATH 與 GNU md5sum 指令相容,可直接管道導入 sort、uniq -w 32 偵測重複檔案:
ruby md5sum.rb /data | sort | uniq -w 32 -D
Ruby 標準庫 Digest::MD5 + Find/Dir 讓檔案雜湊計算極為簡潔。生產環境務必使用流式讀取避免大檔案記憶體溢位,並配合平行處理充分利用多核心效能。輸出標準格式便於後續 Unix 工具鏈處理。