2013-03-04 29 views
1

我有大約50個CSV文件需要水平合併到一個CSV文件中。我如何將兩個CSV文件水平合併?

標題可以被忽略。一點點簡化了文件看起來是這樣的:

文件1:

1,2,4,5,6 
4,5,68,7,4,2 
1,2 

1,2,3 

文件2:

1,2,4 
4,5,6,4 
3,4,5 
3,4,5 

輸出應該是這樣的:

1,2,4,5,6,1,2,4 
4,5,68,7,4,2,4,5,6,4 
1,2,3,4,5 
3,4,5 
1,2,3 

順序合併文件也並不重要。我知道如何垂直合併它們,但我不知道如何水平合併。 我想過這樣的嵌套數組,但它不起作用,但我不知道爲什麼。好像數據數組不接受線陣列。

#!/usr/bin/env ruby 
require 'csv' 
data = Array.new 
filecount=1 
linecount=1 

CSV.open("output.csv", "wb") do |output| 
    Dir.glob('*.csv').each do |each| 
    next if each == 'output.csv' 
    file = CSV.read(each) 
    file.each do |line| 
     data[filecount][linecount] = line 
     linecount=linecount+1 
    end 
    filecount=filecount+1 
    end 
end 

puts data 
+0

嗯,我應該提到,這些文件非常大。我寫了一個bash腳本來完成這項工作,但它確實很慢。由於服務器具有大約64GB的RAM,應該可以將所有文件加載到內存中。 – user2132453 2013-03-04 16:50:01

+0

我認爲你的循環思路正處於正確的軌道上。你爲什麼不嘗試一下,然後回來與你的結果。 – 2013-03-04 16:52:13

+0

好的,我添加了我的想法。我無法獲得陣列數組中的行,這是我的問題。 – user2132453 2013-03-04 17:25:35

回答

2

我準備了一個小腳本來解決您的問題,並添加了一些註釋以獲得更好的解釋。

主要思想是逐行捕捉輸入,因此不必使用太多內存。

#!/usr/bin/env ruby 
require 'csv' 

# map "treats" each element of the array with the block 
files = Dir.glob('csv/*.csv').map { |file| CSV.open file, 'r' } 

CSV.open("output.csv", "wb") do |out| 
    loop do 
     # shift returns the next line 
     # compact remove nil entries 
     line = files.map { |file| file.shift }.compact 
     # remove entry if file has no row 
     line.reject! { |e| e.empty? } 
     # break the endless loop if no input to handle 
     break if line.empty? 
     out << line.flatten 
    end 
end 
+0

非常感謝。我會盡力完全理解代碼。稍後我會盡力爲我的需要改進它。 – user2132453 2013-03-04 19:53:57

相關問題