El tema de esta entrada es simple, la temática es la siguiente: Se calcula el hash de los datos — en este caso de cada archivo — y se está pendiente de que dos archivos no tengan la misma función hash, de ser así, se tiene un archivo duplicado y se procede con el procesamiento deseado.
Para ejecutar el siguiente programa se necesita:
- Ruby
- La gema Mp3Info
gem install mp3info
#!/usr/bin/env ruby # encoding: utf-8 # Program that looks for duplicate files. # Author: MaG, http://newbieshell.blogspot.com require 'digest/sha2' require 'find' require 'mp3info' class FileRecord attr_reader :file, :sum, :duplicates def initialize(path, sum) @file = path @sum = sum @duplicates = [] end def has_duplicates? not @duplicates.empty? end def add(path) @duplicates.push path end end if ARGV[0].nil? or not File.directory? ARGV[0] $stderr.puts "Use: #$0 <directory>" exit 1 end hsh = {} EMPTY_STRING_SUM = Digest::SHA256.hexdigest '' Find.find(ARGV[0]) do|path| next unless File.file? path puts path sum = nil if path =~ /\.mp3$/i begin mp3 = Mp3Info.new(path) pos, length = mp3.audio_content mp3.close rescue next # discard this problematic file end File.open(path) do|file| file.pos = pos sum = Digest::SHA256.hexdigest(file.read(length)) end else sum = Digest::SHA256.file(path).hexdigest end next if sum == EMPTY_STRING_SUM # nah!, let's use +unless+ unless hsh[sum] hsh[sum] = FileRecord.new(path, sum) else file_record = hsh[sum] file_record.add(path) end end print "\n\nduplicates!\n\n" hsh.each_value do|record| next unless record.has_duplicates? print "#{record.file}:\n->" print record.duplicates.join("\n-> "), "\n\n" endSe utiliza la gema Mp3Info para localizar el segmento de audio y calcular la función hash a dicha parte del archivo. Se hace esto, porque es posible que los metadatos de dos archivos varíen y de esta manera corrompan la singularidad del archivo, aun cuando dichos archivos contengan el mismo audio.
Si bien, el programa utiliza un buen algoritmo, este requiere una cantidad considerable de cálculos, los cuales son directamente proporcionales al tamaño de los archivos dentro del directorio raíz en cuestión. Pero algo si es seguro, encuentra los archivos duplicados.
Conclusión
Es posible implementar este programa en un Shell Script utilizando la herramienta sha256sum y el comando find. Aunque con el Shell será un poco más difícil contrarrestar el problema de los metadatos en los archivos de tipo: mp3, jpeg, png, pdf, etc.
Al parecer, los formatos de audio parecen ser los más propensos a este tipo de casos, donde los metadatos corrompen la función hash. Es muy importante tener esto pendiente para cuando se necesite un poco más de precisión.
Si necesitas una solución utilizando Bash, o necesitas ayuda, deja un comentario o contáctame por correo, el cual está en la parte de arriba de este blog.
No hay comentarios:
Publicar un comentario