For jpeg files, looks in exif for the creation date, if that file has that kind of metadadata. For any other files it only checks the creation time.
The script takes 3 option on the command line. A command which may be -m, -c or -f, a source folder and a destination folder.
Using -c will copy the files from souce to destination, -m will move them, - f will also move them, by making first a copy then a delete. -f option may used when -m doesn't work, the most common situation beeing when you want to move the files from one file system to another(e.g. from your ext3 local hard drive to an external fat32 usb harddrive)
After you organize the files, you can find duplicate items using my previous snippet.
This script have been inspired from here
#!/usr/local/bin/ruby require 'rubygems' require 'ftools' require 'exifr' def process_file(file_path,destination_dir) if File.directory?(file_path) crt_dir = Dir.new(file_path) crt_dir.each do |file_name| if file_name != '.' && file_name != '..' process_file("#{crt_dir.path}/#{file_name}",destination_dir) end end else if File.fnmatch('*.jpg',file_path) || File.fnmatch('*.jpeg',file_path) picture = EXIFR::JPEG.new(file_path) if picture != nil && picture.exif != nil file_date = picture.date_time else f = File.new(file_path) file_date = f.mtime end end if file_date == nil f = File.new(file_path) file_date = f.mtime end year_dir = destination_dir + file_date.strftime("%Y") month_dir = destination_dir + file_date.strftime("%Y/%m-%b") day_dir = destination_dir + file_date.strftime("%Y/%m-%b/%d") new_file_name = day_dir + "/" + File.basename(file_path) begin Dir.mkdir(year_dir) unless File.exists?(year_dir) Dir.mkdir(month_dir) unless File.exists?(month_dir) Dir.mkdir(day_dir) unless File.exists?(day_dir) if ARGV[0 ] =='-m' #move the files File.rename(file_path, new_file_name) elsif ARGV[0] =='-c' #copy the files File.cp(file_path, new_file_name) elsif ARGV[0] =='-f' #copy and delete, acts like a move between thw different file systems File.cp(file_path, new_file_name) File.delete(file_path) else puts "Unknown option #{ARGV[0]}" exit end end end end if ARGV.length != 3 puts "Three arguments are required to run the script, -c|-m|-f <source_folder_or_file> <destination_folder>" exit end if ARGV[0] !='-c' && ARGV[0]!='-m' && ARGV[0]!='-f' puts "Unknown running option: #{ARGV[0]}" exit end if not File.exists?(ARGV[1]) puts "Source file does not exists: #{ARGV[1]}" exit end if not File.directory?(ARGV[2]) puts "Destination file is not a directory #{ARGV[2]}" exit end if ARGV[1]==ARGV[2] puts "Source and destination must be different" exit end process_file(ARGV[1], ARGV[2])