रूबी में सीएसवी को आउटपुट सरणी


185

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

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


3
आपके पास इसका उत्तर बहुत अच्छा है, लेकिन मैं आपसे आग्रह करता हूं कि आप सीएसवी का उपयोग न करें। यदि आपके डेटा में टैब नहीं हैं, तो टैब-सीमांकित फ़ाइलों से निपटना बहुत आसान है क्योंकि वे बहुत अधिक फ्रीकिन को उद्धृत करने और भागने और इस तरह से शामिल नहीं हैं। यदि आप CSV का उपयोग करते हैं, तो निश्चित रूप से, वे ब्रेक हैं।
बिल लॉबर

8
@ बिल, CSV मॉड्यूल बड़े पैमाने पर टैब-सीमांकित फ़ाइलों के साथ-साथ वास्तविक csv फ़ाइलों को संभालता है। : Col_sep विकल्प आपको कॉलम विभाजक को "\ t" और सभी की भलाई के रूप में निर्दिष्ट करने देता है।
तामूस


इस मॉड्यूल के साथ .tab फ़ाइलों का उपयोग करना, जो मैं कर रहा हूं, क्योंकि एक्सेल में इसे दुर्घटना से खोलना एन्कोडिंग को गड़बड़ कर देगा ...
MrVocabulary

जवाबों:


326

एक फ़ाइल के लिए:

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

एक स्ट्रिंग के लिए:

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

यहां CSV पर वर्तमान दस्तावेज़ हैं: http://ruby-doc.org/stdlib/libdoc/csv/rdoc/index.html


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

15
पकड़ लिया। और भविष्य के उपयोगकर्ताओं के लिए, यदि आप चाहते हैं कि प्रत्येक पुनरावृत्ति पिछली सीएसवी फ़ाइल को अधिलेखित न करे, तो "अब" विकल्प का उपयोग करें।
बोल्डर_रुबी

1
रूबी फ़ाइल IO मोड के लिए यह उत्तर देखें: stackoverflow.com/a/3682374/224707
Nick

38

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

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

Hmm @tamouse, कि gist csv स्रोत को पढ़े बिना मुझे कुछ भ्रमित कर रहा है, लेकिन उदारता से, आपके सरणी में प्रत्येक हैश को k / v युग्मों की संख्या समान है और यह कि कुंजियाँ हमेशा समान होती हैं, उसी क्रम में (अर्थात यदि आपका डेटा संरचित है), तो यह काम करना चाहिए:

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

यदि आपका डेटा संरचित नहीं है, तो यह स्पष्ट रूप से काम नहीं करेगा


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

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

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

3
आप injectयहाँ दुरुपयोग कर रहे हैं, आप वास्तव में उपयोग करना चाहते हैं map। इसके अलावा, आपको खाली स्ट्रिंग को पास करने की आवश्यकता नहीं है join, क्योंकि यह डिफ़ॉल्ट है। तो आप इसे आगे भी सिकोड़ सकते हैं:rows.map(&CSV.method(:generate_line).join
iGEL

1
आपका दूसरा उदाहरण अतिविशिष्ट है, क्योंकि CSV पुस्तकालय काफी शक्तिशाली है। CSV.generate(headers: hsh.first&.keys) { |csv| hsh.each { |e| csv << e } }समतुल्य CSV बनाता है।
अमदन

28

यदि आपके पास डेटा का सरणियों का एक सरणी है:

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

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

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

20

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

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

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


9

@ Boulder_ruby के उत्तर पर बिल्डिंग, यह वही है जिसकी मैं तलाश कर रहा हूं, यह मानते हुए 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 पर जिस्ट अपडेट करें


2

खुद के साथ इस संघर्ष। यह मेरा लेना है:

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) ]

Btw, JRuby पर pry में बहुआयामी सरणियों से सावधान रहें। [ %w(your array), %w(goes here) ]सुंदर नहीं लगेगा। github.com/pry/pry/issues/568
फेलिक्स राबे
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.