【发布时间】:2011-05-31 06:14:07
【问题描述】:
我在 Ruby 脚本中有一个方法,它试图在保存文件之前重命名文件。它看起来像这样:
def increment (path)
if path[-3,2] == "_#"
print " Incremented file with that name already exists, renaming\n"
count = path[-1].chr.to_i + 1
return path.chop! << count.to_s
else
print " A file with that name already exists, renaming\n"
return path << "_#1"
end
end
假设您有 3 个同名文件保存到一个目录中,我们会说该文件名为 example.mp3。这个想法是第一个将被保存为example.mp3(因为它不会被脚本中其他地方的if File.exists?("#{file_path}.mp3")捕获),第二个将被保存为example_#1.mp3(因为它被else捕获)上述方法的一部分),第三个为example_#2.mp3(因为它被上述方法的if部分捕获)。
我的问题是双重的。
1) if path[-3,2] == "_#" 不适用于整数超过一位的文件(例如example_#11.mp3),因为字符位置将是错误的(您需要将其设置为path[-4,2],但那不能处理 3 位数字等)。
2) 我从来没有遇到过问题 1),因为该方法不能可靠地捕获文件名。目前它将第一个重命名为example_#1.mp3,但第二个被重命名为相同的东西(导致它覆盖以前保存的文件)。
这对于 Stack Overflow 来说可能太模糊了,但我找不到任何可以解决递增字符串特定部分的问题。
提前致谢!
编辑/更新:
Wayne 下面的方法似乎可以单独工作,但在作为整个脚本的一部分包含时却不能 - 它可以增加一个文件一次(从 example.mp3 到 example_#1.mp3)但不能处理 example_#1.mp3 和将其增加到example_#2.mp3。为了提供更多上下文 - 当前,当脚本找到要保存的文件时,会将名称传递给 Wayne 的方法,如下所示:
file_name = increment(image_name)
File.open("images/#{file_name}.jpeg", 'w') do |output|
open(image_url) do |input|
output << input.read
end
end
我稍微编辑了韦恩的脚本,现在看起来像这样:
def increment (name)
name = name.gsub(/\s{2,}|(http:\/\/)|(www.)/i, '')
if File.exists?("images/#{name}.jpeg")
_, filename, count, extension = *name.match(/(\A.*?)(?:_#(\d+))?(\.[^.]*)?\Z/)
count = (count || '0').to_i + 1
"#{name}_##{count}#{extension}"
else
return name
end
end
我哪里错了?再次,提前致谢。
【问题讨论】:
-
我们需要知道 file_name 的内容才能确定出了什么问题,但是我的函数和@Phrog 都在递增的文件名中包含扩展名(例如'.jpeg')。尝试将
"images/#{file_name}.jpeg"更改为"images/#{file_name}"。如果 file_name 也包含路径,您还可以删除images/留下File.open(filename, ...) -
file_name不包含路径或扩展名。我想我已经发现了问题:当增量运行if File.exists?("images/#{name}.jpeg")时,它只检查非增量文件(例如example.jpeg)。当超过 2 个具有相同file_name的文件在第 2 个之后出现时,被写入example_#1.jpeg。这有意义吗? -
我认为文件名需要从一开始就包含路径和扩展名。那应该可以解决它。除了变量名,它可能应该是
path而不是filename以便代码说的是实话。 -
@Wayne,完美地修复了它。谢谢!