我收到了一份需要更新的CSV文件。在当前状态下,它存储超过13,000个文件的上传名称和日期,但是许多条目都是重复的。如果文件名的前九位数相同,则该条目被视为重复,但我想保留每个副本的最新副本。我一直在研究一个Ruby程序,它将创建一个新的CSV文件,其中包含需要删除的重复文件的所有文件名,但我对Ruby(不到一周)的经验很少,所以我是挣扎。包含所有文件的原始CSV已按文件名排序,因此重复项彼此相邻,因此我编写了此代码:
require 'rubygems'
require 'csv'
updated_name = "FilesToDelete.csv"
previous = nil
filenames = CSV.read('All_filenames.csv')
duplicates = []
CSV.open(updated_name, "w") do |files|
files << filenames.shift
filenames.each do |row|
next if row[0] == previous #This is where I don't know how to compare only first nine characters of the string
previous = row[0]
files << row
end
end
我真的不知道如何使用Ruby来完成这项任务,所以这段代码可能非常错误。如果你知道这样做的方法,任何帮助将不胜感激。我使用这个帖子得到了这个:ruby CSV duplicate row parsing
答案 0 :(得分:0)
比较前9个字符:
row[0,9] == previous[0,9]
字符串上的[0,9]
是“从零偏离处开始,返回九个字符”的表示法,是String#[]
方法的一部分。
请注意,您没有更新previous
,因此它始终是相同的。这是另一种方法:
filenames.each_with_index do |name, i|
if (row == 0 || row[0,9] != filenames[i-1][0,9])
files << row
end
end
each_with_index
方法与each
类似,但在末尾包含一个索引值,在这种情况下代表行号。
答案 1 :(得分:0)
所以我设法解决了我的问题。我做的第一件事是更改原始CSV文件,以便第一列只有每个文件名的前九个字符。然后,我按前九个字符对CSV文件进行排序,然后按反向时间顺序创建日期。这种允许我使用这段代码:
require 'rubygems'
require 'csv'
updated_name = "AllFilesForArchive.csv" # This should be changed based on which operation is used
previous = nil
filenames = CSV.read('All_filenames.csv')
duplicates = []
CSV.open(updated_name, "w") do |files|
files << filenames.shift
filenames.each do |row|
# Next three lines are used to only list files to keep
#next if duplicates.include?(row[0]))
#duplicates.unshift row[0]
#files << row
# This if-else statement is used to only lists files to archive
if row[0] == previous
files << row
else
previous = row[0]
end
end
end
因此,此代码允许我创建一个包含要保留的文件的新CSV以及一个单独的新CSV,其中列出了要删除的所有文件,具体取决于我在评论中添加的.each do
部分。