2011-01-27 6 views
134

में सीएसवी के आउटपुट सरणी रूबी के साथ एक सरणी में एक CSV फ़ाइल पढ़ने के लिए काफी आसान है, लेकिन मुझे CSV फ़ाइल में सरणी लिखने के तरीके पर कोई अच्छा दस्तावेज़ नहीं मिल रहा है। क्या कोई मुझे बता सकता है कि इसे कैसे करना है?रूबी

मैं रूबी 1.9.2 का उपयोग कर रहा हूं यदि यह मायने रखता है।

+3

जवाब आपके पास अच्छा है, लेकिन मुझे आपको सीएसवी का उपयोग न करने का आग्रह करता हूं। यदि आपके डेटा में टैब नहीं हैं, तो टैब-डिलीमिट की गई फ़ाइलों को निपटने के लिए बहुत आसान है क्योंकि उनमें इतनी अधिक freakin 'उद्धरण और भागने और शामिल नहीं है। यदि आपको सीएसवी का उपयोग करना चाहिए, तो निश्चित रूप से, वे ब्रेक हैं। –

+7

@ बिल, सीएसवी मॉड्यूल अच्छी तरह से टैब-सीमांकित फ़ाइलों के साथ-साथ वास्तविक सीएसवी फाइलों को संभालता है। : Col_sep विकल्प आपको कॉलम सेपरेटर को "\ t" के रूप में निर्दिष्ट करने देता है और सब कुछ ठीक है। – tamouse

+1

यहां CSV के बारे में अधिक जानकारी है http://docs.ruby-lang.org/en/2.1.0/CSV.html –

उत्तर

246
एक फाइल करने के लिए

:

require 'csv' 
CSV.open("myfile.csv", "w") do |csv| 
    csv << ["row", "of", "CSV", "data"] 
    csv << ["another", "row"] 
    # ... 
end 

एक स्ट्रिंग के लिए: http://ruby-doc.org/stdlib/libdoc/csv/rdoc/index.html

+0

"डब्ल्यू" के लिए क्या है? –

+1

@ डेविड यह फ़ाइल मोड है। "डब्ल्यू" का अर्थ है फाइल को लिखें। यदि आप इसे निर्दिष्ट नहीं करते हैं, तो यह "आरबी" (केवल-पढ़ने वाली बाइनरी मोड) के लिए डिफ़ॉल्ट होगा और आपको अपनी सीएसवी फ़ाइल में जोड़ने का प्रयास करते समय एक त्रुटि मिलेगी। रूबी में वैध फ़ाइल मोड की सूची के लिए http://www.ruby-doc.org/core-1.9.3/IO.html देखें। –

+12

गोचा। और भविष्य के उपयोगकर्ताओं के लिए, यदि आप चाहते हैं कि प्रत्येक पुनरावृत्ति पिछली सीएसवी फ़ाइल को ओवरराइट न करें, तो "ab" विकल्प का उपयोग करें। –

2

इस के साथ अपने आप संघर्ष:

require 'csv' 
csv_string = CSV.generate do |csv| 
    csv << ["row", "of", "CSV", "data"] 
    csv << ["another", "row"] 
    # ... 
end 

यहां पर CSV पर वर्तमान प्रलेखन है।

https://gist.github.com/2639448:

require 'csv' 

class CSV 
    def CSV.unparse array 
    CSV.generate do |csv| 
     array.each { |i| csv << i } 
    end 
    end 
end 

CSV.unparse [ %w(your array), %w(goes here) ] 
+0

बीटीडब्ल्यू, जेआरबी पर प्रिये में बहु-आयामी सरणी से सावधान रहें। '[% डब्ल्यू (आपकी सरणी),% डब्ल्यू (यहां जाती है)] 'सुंदर दिखाई नहीं देगी। https://github.com/pry/pry/issues/568 –

27

मैं सिर्फ एक लाइन के लिए नीचे इस मिल गया है यह मेरा ले रहा है।

rows = [['a1', 'a2', 'a3'],['b1', 'b2', 'b3', 'b4'], ['c1', 'c2', 'c3'], ... ] 
csv_str = rows.inject([]) { |csv, row| csv << CSV.generate_line(row) }.join("") 
#=> "a1,a2,a3\nb1,b2,b3\nc1,c2,c3\n" 

एक पंक्ति में एक csv को बचाने के ऊपर और के सभी करते हैं,।

File.open("ss.csv", "w") {|f| f.write(rows.inject([]) { |csv, row| csv << CSV.generate_line(row) }.join(""))} 

नोट:

इस तरह बदलने के लिए सीएसवी को एक सक्रिय रिकॉर्ड डेटाबेस कुछ होगा मुझे लगता है कि

CSV.open(fn, 'w') do |csv| 
    csv << Model.column_names 
    Model.where(query).each do |m| 
    csv << m.attributes.values 
    end 
end 

हम्म @tamouse, कि सार के बिना मेरे लिए कुछ भ्रामक है सीएसवी स्रोत को पढ़ना, लेकिन आम तौर पर, मानते हैं कि आपके सरणी में प्रत्येक हैश की संख्या समान संख्या में के/वी जोड़े & है कि कुंजी हमेशा एक ही क्रम में होती है (यानी यदि अपने डेटा को बनाया गया है), इस काम करना चाहिए:

rowid = 0 
CSV.open(fn, 'w') do |csv| 
    hsh_ary.each do |hsh| 
    rowid += 1 
    if rowid == 1 
     csv << hsh.keys# adding header row (column labels) 
    else 
     csv << hsh.values 
    end# of if/else inside hsh 
    end# of hsh's (rows) 
end# of csv open 

अपने डेटा इस स्पष्ट रूप से संरचित नहीं है, तो @ boulder_ruby के जवाब पर

+0

मैंने CSV.table का उपयोग कर एक CSV फ़ाइल में खींचा, कुछ मैनिप्लेशंस किए, कुछ कॉलम से छुटकारा पा लिया, और अब मैं हेशेस के परिणामस्वरूप ऐरे को फिर से स्पूल करना चाहता हूं सीएसवी के रूप में (वास्तव में टैब-सीमांकित)। कैसे? https://gist.github.com/4647196 – tamouse

+0

हम्म ... वह जिस्ट कुछ हद तक अपारदर्शी है, लेकिन हैश की एक सरणी दी गई है, सभी एक ही क्रम में के/वी जोड़े और एक ही कुंजी के समान हैं .. –

+0

धन्यवाद, @boulder_ruby। वह काम करेगा। डेटा एक जनगणना तालिका है, और वह गलती इसके बजाय वापस देखकर अपारदर्शी है। :) यह मूल रूप से मूल जनगणना तालिका से कुछ सबमेट्स को सबसेट में निकालने जा रहा है। – tamouse

7

भवन से काम नहीं चलेगा, यह मैं क्या देख रहा हूँ है , us_eco मानते हुए मेरे जीस्ट के रूप में सीएसवी तालिका शामिल है।

CSV.open('outfile.txt','wb', col_sep: "\t") do |csvfile| 
    csvfile << us_eco.first.keys 
    us_eco.each do |row| 
    csvfile << row.values 
    end 
end 

https://gist.github.com/tamouse/4647196

13

पर सार अपडेट किया गया तो किसी को दिलचस्पी है, यहाँ कुछ एक-लाइनर्स (और CSV में प्रकार की जानकारी के नुकसान पर एक नोट) हैं:

require 'csv' 

rows = [[1,2,3],[4,5]]     # [[1, 2, 3], [4, 5]] 

# To CSV string 
csv = rows.map(&:to_csv).join    # "1,2,3\n4,5\n" 

# ... and back, as String[][] 
rows2 = csv.split("\n").map(&:parse_csv) # [["1", "2", "3"], ["4", "5"]] 

# File I/O: 
filename = '/tmp/vsc.csv' 

# Save to file -- answer to your question 
IO.write(filename, rows.map(&:to_csv).join) 

# Read from file 
# rows3 = IO.read(filename).split("\n").map(&:parse_csv) 
rows3 = CSV.read(filename) 

rows3 == rows2 # true 
rows3 == rows # false 

नोट: सीएसवी सभी प्रकार की जानकारी खो देता है, आप मूल प्रकार की जानकारी को संरक्षित करने के लिए JSON का उपयोग कर सकते हैं, या सभी प्रकार की जानकारी को संरक्षित करने के लिए वर्बोज़ (लेकिन अधिक आसानी से मानव-संपादन योग्य) YAML पर जाएं - उदाहरण के लिए, यदि आपको दिनांक प्रकार की आवश्यकता है, जो CSV में स्ट्रिंग बन जाएगा & JSON।आप डेटा के सरणियों की एक सरणी है, तो

10

:

rows = [["a1", "a2", "a3"],["b1", "b2", "b3", "b4"], ["c1", "c2", "c3"]] 

तो फिर तुम निम्नलिखित है, जो मुझे लगता है कि के साथ एक फ़ाइल को यह लिख सकते हैं बहुत सरल है:

require "csv" 
File.write("ss.csv", rows.map(&:to_csv).join)