How to mass rename files in ruby

前端 未结 5 1176
梦谈多话
梦谈多话 2021-02-20 02:21

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

相关标签:
5条回答
  • 2021-02-20 03:02

    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
      end
    end
    

    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.

    0 讨论(0)
  • 2021-02-20 03:09

    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

    0 讨论(0)
  • 2021-02-20 03:14

    Here's a short version I've used today (without pattern matching)

    Save this as rename.rb file and run it inside the command prompt with ruby rename.rb

    count = 1
    newname = "car"
    Dir["/path/to/folder/*"].each do |old|
      File.rename(old, newname + count.to_s)
      count += 1
    end
    

    I had /Copy of _MG_2435.JPG converted into car1, car2, ...

    0 讨论(0)
  • 2021-02-20 03:16

    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
    
    0 讨论(0)
  • 2021-02-20 03:19

    I used the accepted answer to fix a bunch of copied files' names.

    Dir.glob('./*').sort.each do |entry|
      if File.basename(entry).include?(' copy')
        newEntry = entry.gsub(' copy', '')
        File.rename( entry, newEntry )
      end
    end
    
    0 讨论(0)
提交回复
热议问题