如何在ruby中批量重命名文件

时间:2012-05-25 17:14:30

标签: ruby

我一直在努力找出一个基于ruby的文件重命名程序,作为我自己的编程练习(我知道在linux下重命名,但我想学习Ruby,并且Mac中没有重命名)。

从下面的代码中,问题是.include?方法总是返回false,即使我看到文件名包含这样的搜索模式。如果我注释掉include?检查,gsub()似乎根本不会生成新的文件名(即文件名保持不变)。所以有人可以看看我做错了什么吗?提前一堆谢谢!

这是预期的行为: 假设在当前文件夹中有三个文件:a1.jpg,a2.jpg和a3.jpg Ruby脚本应该能够将其重命名为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

5 个答案:

答案 0 :(得分:11)

略有修改版本:

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

主要差异:

  • 使用.strip删除从gets获得的尾随换行符。否则,这个换行符会搞砸你所有的比赛尝试。
  • glob调用中使用用户提供的搜索模式,而不是为所有内容进行通配,然后稍后手动过滤。
  • entrygsub而非rename的调用中使用origin(即完整的文件名)。 origin实际上只对.include?测试有用。由于它是文件名的片段,因此不能与rename一起使用。我完全删除了origin变量,以避免误用它。

对于示例文件夹结构,输入*.jpgab分别输入三个输入提示应该按照您的预期重命名文件。

答案 1 :(得分:3)

我使用接受的答案来修复一堆复制文件的名称。

Dir.glob('./*').sort.each do |entry|
  if File.basename(entry).include?(' copy')
    newEntry = entry.gsub(' copy', '')
    File.rename( entry, newEntry )
  end
end

答案 2 :(得分:2)

您的问题是gets在字符串末尾返回换行符。因此,如果您输入“foo”,则searchPattern会变为"foo\n"。最简单的解决方法是:

searchPattern = gets.chomp

我可能会稍微改写你的代码:

$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

答案 3 :(得分:1)

这是我今天使用的简短版本(没有模式匹配)

将其另存为rename.rb文件并使用 ruby​​ rename.rb

在命令提示符下运行
count = 1
newname = "car"
Dir["/path/to/folder/*"].each do |old|
  File.rename(old, newname + count.to_s)
  count += 1
end

我将_MG_2435.JPG的副本转换为car1,car2,......

答案 4 :(得分:0)

我编写了一个小脚本,按季节重命名整个DBZ系列,并实现了这一点:

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

结果将是:     七龙珠Z S05E1     七龙珠Z S05E2     龙珠Z S05E3