CSV文件Ruby中的重复存档器

时间:2015-06-26 18:27:39

标签: ruby-on-rails ruby csv

我收到了一份需要更新的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

2 个答案:

答案 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部分。