Antony Antony - 3 months ago 8x
Ruby Question

How to mass rename files in ruby

I have been trying to work out a file rename program based on ruby, as a programming exercise for myself (I am aware of rename under linux, but I want to learn Ruby, and rename is not available in Mac).

From the code below, the issue is that the

method always returns false even though I see the filename contains such search pattern. If I comment out the
does not seem to generate a new file name at all (i.e. file name remains the same). So can someone please take a look at see what I did wrong? Thanks a bunch in advance!

Here is the expected behavior:
Assuming that in current folder there are three files: a1.jpg, a2.jpg, and a3.jpg
The Ruby script should be able to rename it to b1.jpg, b2.jpg, b3.jpg


puts "Enter the file search query"
searchPattern = gets
puts "Enter the target to replace"
target = gets
puts "Enter the new target name"
newTarget = gets
Dir.glob("./*").sort.each do |entry|
origin = File.basename(entry, File.extname(entry))
if origin.include?(searchPattern)
newEntry = origin.gsub(target, newTarget)
File.rename( origin, newEntry )
puts "Rename from " + origin + " to " + newEntry

bta bta

Slightly modified version:

puts "Enter the file search query"
searchPattern = gets.strip
puts "Enter the target to replace"
target = gets.strip
puts "Enter the new target name"
newTarget = gets.strip
Dir.glob(searchPattern).sort.each do |entry|
  if File.basename(entry, File.extname(entry)).include?(target)
    newEntry = entry.gsub(target, newTarget)
    File.rename( entry, newEntry )
    puts "Rename from " + entry + " to " + newEntry

Key differences:

  • Use .strip to remove the trailing newline that you get from gets. Otherwise, this newline character will mess up all of your match attempts.
  • Use the user-provided search pattern in the glob call instead of globbing for everything and then manually filtering it later.
  • Use entry (that is, the complete filename) in the calls to gsub and rename instead of origin. origin is really only useful for the .include? test. Since it's a fragment of a filename, it can't be used with rename. I removed the origin variable entirely to avoid the temptation to misuse it.

For your example folder structure, entering *.jpg, a, and b for the three input prompts (respectively) should rename the files as you are expecting.