válido tener selecciona puede por menos importación fichero falló enviado delimitar delimitado datos convertir con compatibles como comas caracteristicas archivo ruby tsv

tener - ¿Cuál es la mejor manera de analizar un archivo delimitado por tabuladores en Ruby?



puede tener caracteristicas no compatibles con csv delimitado por comas (3)

¿Cuál es la mejor (la más eficiente) forma de analizar un archivo delimitado por tabuladores en Ruby?


La biblioteca Ruby CSV le permite especificar el delimitador de campo. Ruby 1.9 usa FasterCSV . Algo como esto funcionaría:

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


Las reglas para TSV son en realidad un poco diferentes de CSV. La principal diferencia es que CSV tiene disposiciones para pegar una coma dentro de un campo y luego usar los caracteres de comillas y las comillas de escape dentro de un campo. Escribí un ejemplo rápido para mostrar cómo falla la respuesta simple:

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

Si desea utilizar la biblioteca CSV, podría utilizar un carácter de comillas al azar que no espera ver si su archivo (el ejemplo lo muestra), pero también podría usar una metodología más simple como la clase StrictTsv que se muestra a continuación para obtener el mismo efecto sin tener que preocuparse por las citas de campo.

# 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

La elección de utilizar la biblioteca CSV o algo más estricto depende de quién le envía el archivo y si están esperando adherirse al estricto estándar TSV.

Los detalles sobre el estándar TSV se pueden encontrar en http://en.wikipedia.org/wiki/Tab-separated_values


Me gusta la respuesta de mmmries. SIN EMBARGO, odio la forma en que el rubí elimina cualquier valor vacío del final de una división. Tampoco se está quitando la nueva línea al final de las líneas.

Además, tenía un archivo con nuevas líneas potenciales dentro de un campo. Entonces, reescribí su ''análisis'' de la siguiente manera:

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

Concatena las líneas según sea necesario para obtener una línea completa de datos, y siempre devuelve el conjunto completo de datos (sin posibles entradas nulas al final).