2013-03-04 3 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

+0

나는 당신이 당신의 while 루프 아이디어로 바른 길을 가고 있다고 생각합니다. 그것을 시도해 보시고, 결과와 함께 다시 여기에 오십시오. –

+0

OK 제 아이디어를 추가했습니다. 배열의 배열에 줄을 가져올 수 없습니다. 내 문제입니다. – user2132453

답변

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

관련 문제