Skip to content

Instantly share code, notes, and snippets.

@ymek
Created November 29, 2012 06:57
Show Gist options
  • Select an option

  • Save ymek/4167273 to your computer and use it in GitHub Desktop.

Select an option

Save ymek/4167273 to your computer and use it in GitHub Desktop.
Quickly sort related files in a given directory into subdirectories
#! /usr/bin/env ruby
##
# Quickly sort related files in a given directory into
# subdirectories of that same directory
#
# defaults to the current working directory if no supplied path
require 'fileutils'
base_dir = ARGV[0] || Dir.pwd
Dir.chdir base_dir do
# all non-directory files, then sort them
files = Dir.glob('*').reject { |f| File.directory?(f) }
files.map(&:downcase).sort!
files.each do |file|
# determine the delimiter (better if it found most-frequent-matched character)
# build a pattern to match filenames against (Should only contain the first
# characters and words of each file name)
# bail if the pattern is too short
delimiter = file[/[\W_]/]
parts = []
file.split(delimiter).each do |part|
break if part[/^\D{2,}/].nil? && (!parts.empty? && part.length > 1)
parts << part
end
pattern = parts.join(delimiter).gsub(/\./, '\.').downcase
next unless pattern.length > 4
# match all files against the previously-built patter
# if a pattern matches more than one file, create a
# directory for that pattern and move all matching
# files into said directory
# delete any matched file names from the files array
matches = files.select { |f| f[/#{pattern}/i] }
if matches.count > 1
relname = pattern.split(delimiter).map(&:capitalize).join(delimiter).gsub(/\\\./, '.')
dirname = File.join(base_dir, relname)
unless Dir.exists?(dirname)
puts "=> Creating Directory: #{dirname}"
Dir.mkdir(dirname)
end
matches.each do |fname|
old_file = File.join(base_dir, fname)
new_file = File.join(dirname, fname)
puts "-> Moving #{fname}"
FileUtils.mv(old_file, new_file)
files.delete(fname)
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment