如何将多个CSV文件合并为一个,只包含唯一值

时间:2014-12-08 03:42:31

标签: ruby csv

我在目录中有多个CSV文件,所有这些文件都具有相同的数据模型,其中一些是重复的。

file1.csv:

1       joe      red
2       bill     blue 
3       bob      green

file2.csv:

3       bob      green
4       mary     white 
5       jim      yellow

file3.csv:

5       jim      yellow
6       lauren    pink  
7       george    purple

我的目标是生成包含所有唯一值的单个CSV文件。

到目前为止,我的代码是:

  1. 使用

    连接iTerm2中的所有文件
     cat *.csv > combined.csv
    
  2. 这个脚本:

    require 'csv'
    
    File.open("all_unique_rows.csv", "w+") { 
    
      |file| file.puts File.readlines("combined.csv").uniq 
    
    }
    
  3. 但是,我希望能够从单个Ruby脚本中完成所有操作,但是我不知道如何使用Ruby将“combined.csv”文件作为一个巨大的文件。

1 个答案:

答案 0 :(得分:4)

如果您的记录是真实的重复,我不会在Ruby中这样做。相反,利用操作系统中的现有工具:

cat *.csv | sort -u >unique.csv

完成后," unique.csv"将包含唯一记录。

如果你坚持用Ruby编写它,那么就可以利用内置的方法或类。这是一种未经测试的方法:

require 'set'
unique = Set.new
Dir.glob('*.csv') do |f|
  File.foreach(f) { |l| unique << l }
end
File.write('unique.csv', unique.sort.join)

这可以创建一个独特的输出,因为集合不允许重复。

另一种方法是做一些事情:

unique = []
Dir.glob('*.csv') do |f|
  unique += File.readlines(f)
end
File.write('unique.csv', unique.sort.uniq.join)

虽然Ruby 可以这样做,但使用操作系统处理它可以更具可扩展性。因人而异。


  

我尝试过运行cat * .csv |排序 - 你&gt;操作系统中的unique.csv,但最终将一些值错放到了错误的列中。

我在磁盘上创建了三个文件:

$ cat file1.csv
1       joe      red
2       bill     blue
3       bob      green
$ cat file2.csv
3       bob      green
4       mary     white
5       jim      yellow
$ cat file3.csv
5       jim      yellow
6       lauren    pink
7       george    purple

运行cat *.csv | sort -u >unique.csv并查看生成的文件显示:

$ cat unique.csv
1       joe      red
2       bill     blue
3       bob      green
4       mary     white
5       jim      yellow
6       lauren    pink
7       george    purple

删除重复项,文件与您提供的输入样本相同。你的&#34; file3.csv&#34;在最后一行显示一个额外的空格,将最右边的列推到最后。

注意:您的文件是 NOT CSV文件。 CSV代表&#34;以逗号分隔的值&#34;并且列之间没有逗号。您可能最初拥有TSV(&#34;制表符分隔值&#34;),Ruby的CSV类可以读取和写入,或者您有固定宽度的列,并以某种方式添加了额外的空间。使用正确的术语并始终如一地这一点非常重要,尤其是在提问时。