【问题标题】:CSV File Duplicate Archiver in RubyRuby 中的 CSV 文件重复存档器
【发布时间】:2015-06-26 18:27:39
【问题描述】:

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

【问题讨论】:

  • 这个 csv 文件,每行是否包含一个文件名(仅此而已)?
  • 我会为此使用一个小型 SQLite 数据库。这将允许您轻松加载 CSV、更新它、删除重复并输出带有文件最新时间戳的 CSV。
  • @steenslag 没有 8 列,包括创建日期等,但其他列对于每个文件都相同或不需要。我只是想包含在新 CSV 中创建的文件名和日期。

标签: ruby-on-rails ruby csv


【解决方案1】:

比较前 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,但在末尾包含一个索引值,在这种情况下,它表示行号。

【讨论】:

  • 我试着按照你说的去做,但是它导致了一个错误(因为name应该是row,对吧?)。即使我将其切换到row,该程序也只是从原始版本中复制了所有内容。自最初发布以来,我设法按文件和上传日期对原始 CSV 进行排序。
【解决方案2】:

所以我设法解决了我的问题。我做的第一件事是更改原始 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,其中列出了要删除的所有文件,这取决于我在 cmets 中放入的 .each do 的哪个部分。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-19
    • 2014-02-11
    • 2018-05-15
    相关资源
    最近更新 更多