免责声明:我不是程序员,从来没有,从未学过算法,CS等等。只需要使用它。
我的问题是:我需要根据第一个字段将一个巨大的(超过4 GB)CSV文件拆分成较小的文件(然后用require 'win32ole'
处理)。在awk中它很容易:
awk -F ',' '{myfile=$1 ; print $0 >> (myfile".csv")}' KNAGYFILE.csv
但是ruby
我做了:
open('hugefile').each { |hline|
accno = hline[0,12]
nline = hline[13,10000].gsub(/;/,",")
accfile = File.open("#{accno.to_s}.csv", "a")
accfile.puts nline
accfile.close
}
然后认识到资源效率低下(几个文件打开/关闭)。我确信有更好的方法,你可以解释一下吗?
更新:只是忘了提及,文件在第一列上排序。例如。如果这是hugefile:
012345678901,1,1,1,1,1,1
012345678901,1,2,1,1,1,1
012345678901,1,1,A,1,1,1
012345678901,1,1,1,1,A,A
A12345678901,1,1,1,1,1,1
A12345678901,1,1,1,1,1,1
A12345678901,1,1,1,1,1,1
A12345678901,1,1,1,1,1,1
然后我需要两个名为012345678901.csv
和A12345678901.csv
的新文件。
答案 0 :(得分:2)
你的awk解决方案必须多次打开文件,所以我认为你会得到相同的资源使用。
您可以保持文件打开,直到$ 1更改:
prev = nil
File.foreach('hugefile') do |hline|
accno = hline[0,12]
nline = hline[13,10000].gsub(/;/,",")
if prev != accno
accfile.close rescue nil
accfile = File.open("#{accno.to_s}.csv", "a")
prev = accno
end
accfile.puts nline
end
答案 1 :(得分:1)
这应该解决多开放写入关闭问题,尽管如果文件数量变大可能会遇到问题;我不能说,我从来没有打开过数百个文件!
第一行是重要的一行:对于遇到的每个新密钥,它会打开一个新文件并将其存储在哈希中的该密钥中。最后一行关闭所有打开的文件。
files = Hash.new { |h, k| h[k] = File.open("#{k}.csv", 'w+') }
open('hugefile').each do |hline|
files[hline[0,12]].puts hline[13,10000].gsub(/;/,",")
end
files.each { |n, f| f.close }