Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to mass rename files in ruby

Tags:

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 .include? method always returns false even though I see the filename contains such search pattern. If I comment out the include? check, gsub() 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

#!/Users/Antony/.rvm/rubies/ruby-1.9.3-p194/bin/ruby

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
  end
end
like image 790
Antony Avatar asked May 25 '12 17:05

Antony


People also ask

How do I bulk rename files?

Select multiple files in a folder. To do so, press and hold down the CTRL key while you are clicking files. After you select the files, press F2. Type the new name, and then press ENTER.

How do you rename a file in Ruby?

rename(f, filename. capitalize + File. extname(f)) end puts "Renaming complete."

Can you mass edit file names?

To batch rename files, just select all the files you want to rename, press F2 (alternatively, right-click and select rename), then enter the name you want on the first file. Press Enter to change the names for all other selected files.


2 Answers

Your problem is that gets returns a newline at the end of the string. So, if you type "foo" then searchPattern becomes "foo\n". The simplest fix is:

searchPattern = gets.chomp

I might rewrite your code slightly:

$stdout.sync
print "Enter the file search query: "; search  = gets.chomp
print "Enter the target to replace: "; target  = gets.chomp
print "  Enter the new target name: "; replace = gets.chomp
Dir['*'].each do |file|
  # Skip directories
  next unless File.file?(file)
  old_name = File.basename(file,'.*')
  if old_name.include?(search)
    # Are you sure you want gsub here, and not sub?
    # Don't use `old_name` here, it doesn't have the extension
    new_name = File.basename(file).gsub(target,replace)
    File.rename( file, new_path )
    puts "Renamed #{file} to #{new_name}" if $DEBUG
  end
end
like image 135
Phrogz Avatar answered Sep 27 '22 18:09

Phrogz


I made a small script to rename the entire DBZ serie by seasons and implement this:

count = 1
new_name = "Dragon Ball Z S05E"
format_file = ".mkv"
Dir.glob("dragon ball Z*").each do |old_name|
  File.rename(old_name, new_name + count.to_s + format_file)
  count += 1
end

The result would be: Dragon Ball Z S05E1 Dragon Ball Z S05E2 Dragon Ball Z S05E3

like image 31
Cid Santos Avatar answered Sep 27 '22 16:09

Cid Santos