Skip to content

Instantly share code, notes, and snippets.

@dvdsgl
Last active April 15, 2020 12:19
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save dvdsgl/4600317 to your computer and use it in GitHub Desktop.
Save dvdsgl/4600317 to your computer and use it in GitHub Desktop.
Recursively replace a string in a directory by renaming files, directories, and rewriting file contents (e.g. rename.rb . GAIM Pidgin).
#!env ruby
#
# Recursively replace a string in a directory by renaming files, directories, and rewriting file contents:
#
# $ rename.rb . GAIM Pidgin
#
# No changes are made unless -f is specified
DRY = !(ARGV.include? "-f")
# Replace all occurrences of this with that in file.
def replace file, this, that
content = File.read file
if content.include? this
puts "#{file} (#{content.scan(this).count} occurrences of '#{this}')"
unless DRY
content.gsub! this, that
File.open(file, "w") { |f| f.puts content }
end
end
end
# Rename a file or directory
def mv x, y
cmd = "mv #{x} #{y}"
puts cmd
`#{cmd}` unless DRY
end
def rename dir, this, that
Dir.chdir dir do
dirs = Dir["*"].select { |f| File.directory? f }
files = Dir["*"].reject { |f| File.directory? f }
# Traverse subdirectories
dirs.each do |sub|
rename sub, this, that
end
# Change file contents
files.each do |f|
replace f, this, that
end
# Rename files in this directory
Dir["*#{this}*"].each do |f|
mv f, f.sub(this, that)
end
end
end
dir, this, that = ARGV.reject { |x| x =~ /^-/ }
if that
rename dir, this, that
mv dir, dir.sub(this, that) if dir.include? this
puts "(You must include -f to actually perform the replacements)" if DRY
else
puts "Usage: rename.rb DIRECTORY REPLACE_THIS WITH_THIS"
end
@visitdigital
Copy link

beautiful

@johneris
Copy link

johneris commented Jul 9, 2018

thanks!

@dimazen
Copy link

dimazen commented Apr 15, 2020

Wow, thanks for such an amazing script. Was struggling with a bash version of find with no luck. The only thing I would like to propose is to replace

  if content.include? this

by

  if content.valid_encoding? and content.include? this

It fixes exception because of invalid encoding (if any).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment