这是我制作的文本文件重命名器,您将文件放在某个文件夹中,程序将它们重命名为file1.txt,file2.txt等
它完成了工作,但它有两个问题
它给了我这个错误no implicit conversion of nil into String error
如果我将新文件添加到已组织文件的文件夹中,则会删除所有文件,并创建新文件
造成这些问题的原因是什么?
i=0
Dir.chdir 'C:\Users\anon\Desktop\newfolder'
arr = Dir.entries('C:\Users\anon\Desktop\newfolder')
for i in 2..arr.count
if (File.basename(arr[i]) == 'file'+((i-1).to_s)+'.txt')
puts (arr[i]+' is already renamed to '+'file'+i.to_s)
else
File.rename(arr[i],'file'+((i-1).to_s)+'.txt')
end
end
答案 0 :(得分:0)
您的计划有两个主要问题。
首先,您在数组arr
中使用了越界值。试试这个a = [1,2,3]; a[a.count]
,你会得到nil
,因为你正在尝试访问a[3]
但是数组中的最后一个元素有索引2.
然后,您使用fileINDEX.txt
始终为2...foobar
的索引作为索引,而不考虑您的目录中可能已使用某些索引。
额外的问题,您正在使用Dir.entries
,这在我的操作系统中提供了更多.
和..
的常规条目,这些条目应该被正确管理,它们不是您想要操作的。
所以,我写了一个小脚本,我希望你觉得它可读,对我来说它有效。你可以肯定地改进它! (p.s.我在Linux OS下)。
# Global var only to stress its importance
$dir = "/home/p/tmp/t1"
Dir.chdir($dir)
# get list of files
fnames = Dir.glob "*"
# get the max index "fileINDEX.txt" already used in the directory
takenIndexes = []
fnames.each do |f|
if f.match /^file(\d+).txt/ then takenIndexes.push $1.to_i; end
end
# get the first free index available
firstFreeIndex = 1
firstFreeIndex = (takenIndexes.max + 1) if takenIndexes.length > 0
# get a range of fresh indexes for possible use
idxs = firstFreeIndex..(firstFreeIndex + (fnames.length))
# i transform the range to list and reverse the order because i want
# to use "pop" to get and remove them.
idxs = idxs.to_a
idxs.reverse!
# rename the files needing to be renamed
puts "--- Renamed files ----"
fnames.each do |f|
# if file has already the wanted format then move to next iteration
next if f.match /^file\d+.txt/
newName = "file" + idxs.pop.to_s + ".txt"
puts "rename: #{f} ---> #{newName}"
File.rename(f, newName)
end