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

Nic*_*sky 0 ruby csv

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

file1.csv:

1       joe      red
2       bill     blue 
3       bob      green
Run Code Online (Sandbox Code Playgroud)

file2.csv:

3       bob      green
4       mary     white 
5       jim      yellow
Run Code Online (Sandbox Code Playgroud)

file3.csv:

5       jim      yellow
6       lauren    pink  
7       george    purple
Run Code Online (Sandbox Code Playgroud)

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

到目前为止,我拥有的代码是这样的:

  1. 使用以下命令连接iTerm2中的所有文件

     cat *.csv > combined.csv
    
    Run Code Online (Sandbox Code Playgroud)
  2. 这个脚本:

    require 'csv'
    
    File.open("all_unique_rows.csv", "w+") { 
    
      |file| file.puts File.readlines("combined.csv").uniq 
    
    }
    
    Run Code Online (Sandbox Code Playgroud)

但是,我希望能够通过单个Ruby脚本来完成全部操作,但是我不确定如何使用Ruby将“ combined.csv”文件变成一个巨型文件。

the*_*Man 5

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

cat *.csv | sort -u >unique.csv
Run Code Online (Sandbox Code Playgroud)

完成后,“ 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)
Run Code Online (Sandbox Code Playgroud)

这可以创建唯一的输出,因为集不允许重复。

另一种方法是执行以下操作:

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

尽管Ruby 可以做到这一点,但是使用OS处理它的可伸缩性要强得多。YMMV。


我尝试运行cat * .csv | 排序-u> OS中的unique.csv,但最终将某些值放到错误的列中。

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

$ cat file1.csv
1乔红
2比尔蓝色
3鲍勃绿色
$ cat file2.csv
3鲍勃绿色
4玛丽白
5金黄色
$ cat file3.csv
5金黄色
6劳伦粉
7乔治紫色

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

$ cat unique.csv
1乔红
2比尔蓝色
3鲍勃绿色
4玛丽白
5金黄色
6劳伦粉
7乔治紫色

重复项将被删除,并且文件与您提供的输入样本相同。您的“ file3.csv”在最后一行显示一行多余的空间,将最右边的列移到上方。

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