我在目录中有多个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文件。
到目前为止,我拥有的代码是这样的:
使用以下命令连接iTerm2中的所有文件
cat *.csv > combined.csv
Run Code Online (Sandbox Code Playgroud)这个脚本:
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”文件变成一个巨型文件。
如果您的记录是真实的重复记录,那么我不会在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类可以读取和写入,或者您有固定宽度的列并以某种方式增加了额外的空间。使用正确的术语并始终如一地做到这一点非常重要,尤其是在提问时。