2010-12-10 18 views

उत्तर

92

रूबी सीएसवी लाइब्रेरी आपको फील्ड डेलीमीटर निर्दिष्ट करने देता है। रूबी 1.9 FasterCSV का उपयोग करता है। ऐसा कुछ काम करेगा:

require "csv" 
parsed_file = CSV.read("path-to-file.csv", { :col_sep => "\t" }) 
+4

सावधान रहें कि यदि कोई टैब-अलग-अलग मानों में डबल-कोट होता है तो यह दृष्टिकोण विफल हो जाएगा। दूसरे जवाब में StrictTsv सुझाव अधिक मजबूत है। –

23

टीएसवी के नियम वास्तव में सीएसवी से थोड़ा अलग हैं। मुख्य अंतर यह है कि सीएसवी के पास एक क्षेत्र के अंदर एक अल्पविराम चिपकाने के लिए प्रावधान हैं और फिर उद्धरण वर्णों का उपयोग करके और क्षेत्र के अंदर उद्धरण से बचने के प्रावधान हैं। मैं एक त्वरित उदाहरण लिखा था कि कैसे सरल प्रतिक्रिया में विफल रहता है को दिखाने के लिए:

require 'csv' 
line = 'boogie\ttime\tis "now"' 
begin 
    line = CSV.parse_line(line, col_sep: "\t") 
    puts "parsed correctly" 
rescue CSV::MalformedCSVError 
    puts "failed to parse line" 
end 

begin 
    line = CSV.parse_line(line, col_sep: "\t", quote_char: "Ƃ") 
    puts "parsed correctly with random quote char" 
rescue CSV::MalformedCSVError 
    puts "failed to parse line with random quote char" 
end 

#Output: 
# failed to parse line 
# parsed correctly with random quote char 

आप CSV लाइब्रेरी का उपयोग करने के लिए आप एक यादृच्छिक उद्धरण कैरेक्टर है कि आप देखने की उम्मीद नहीं है इस्तेमाल किया जा सकता था चाहते हैं यदि आपकी फ़ाइल (उदाहरण से पता चलता है यह), लेकिन आप फ़ील्ड कोटेशन के बारे में चिंता किए बिना समान प्रभाव प्राप्त करने के लिए नीचे दिखाए गए स्ट्रिक्ट्सवी वर्ग की तरह एक सरल पद्धति का भी उपयोग कर सकते हैं।

# The main parse method is mostly borrowed from a tweet by @JEG2 
class StrictTsv 
    attr_reader :filepath 
    def initialize(filepath) 
    @filepath = filepath 
    end 

    def parse 
    open(filepath) do |f| 
     headers = f.gets.strip.split("\t") 
     f.each do |line| 
     fields = Hash[headers.zip(line.split("\t"))] 
     yield fields 
     end 
    end 
    end 
end 

# Example Usage 
tsv = Vendor::StrictTsv.new("your_file.tsv") 
tsv.parse do |row| 
    puts row['named field'] 
end 

सीएसवी पुस्तकालय या अधिक सख्त कुछ का उपयोग करने का विकल्प सिर्फ जो आप फ़ाइल भेज रहा है पर निर्भर करता है और वे सख्त TSV मानक का पालन करने की उम्मीद कर रहे हैं या नहीं।

TSV मानक के बारे में विवरण http://en.wikipedia.org/wiki/Tab-separated_values

+0

कृपया उत्तर के साथ कोड स्निपेट, बाहरी * में * नहीं * शामिल करें। वह जिस्ट अब नीचे प्रतीत होता है, जो एक वास्तविक शर्म की बात है। –

+4

@ जेज़ेन थॉमस सिर के लिए धन्यवाद। मैंने – mmmries

+0

महान उत्तर को देखने के मुद्दे को ठीक करने के लिए सभी कोड नमूने इनलाइन खींचा। । मुझे आश्चर्य है कि सीएसवी पार्सर के साथ कितना भयंकर \ \' विफल रहता है। – dps

0

में पाया जा सकता मैं mmmries जवाब पसंद है। हालांकि, मुझे इस तरह से नफरत है कि रूबी एक विभाजन के अंत से किसी खाली मूल्य को बंद कर देता है। यह लाइनों के अंत में नई लाइन को अलग नहीं कर रहा है, या तो।

इसके अलावा, मेरे पास एक फ़ील्ड के भीतर संभावित न्यूलाइन वाली एक फ़ाइल थी। तो, मैं अपने 'पार्स' दुबारा लिखा इस प्रकार है:

def parse 
    open(filepath) do |f| 
    headers = f.gets.strip.split("\t") 
    f.each do |line| 
     myline=line 
     while myline.scan(/\t/).count != headers.count-1 
     myline+=f.gets 
     end 
     fields = Hash[headers.zip(myline.chomp.split("\t",headers.count))] 
     yield fields 
    end 
    end 
end 

इस डेटा की एक पूरी लाइन को पाने के लिए आवश्यक के रूप में किसी भी लाइनों संयोजित करता, और हमेशा (अंत में संभावित शून्य प्रविष्टियों के बिना) डेटा का पूरा सेट देता है।

संबंधित मुद्दे

 संबंधित मुद्दे