Табуляцией парсинг файл в Rails
у меня есть файл, который выглядит так
ID Name Car
1 Mike Honda
2 Adam Jim
эти значения разделены табуляцией, и из этого я хочу разобрать его в Ruby и поместить его в свою базу данных.
я попробовал следующее
require 'csv'
CSV.foreach("public/files/example.tab", {:col_sep => "t"}) do |row|
@stuff = row[0]
end
но @stuff
просто возвращает весь объект целиком и, похоже, не использует указанный мной разделитель столбцов.
Он также не учитывает, что первая строка является заголовком.
как я могу разобрать табуляцией файл в Ruby и как сказать ему, что первая строка является заголовком?
3 ответов
У меня был успех с FasterCSV и Ruby 1.8.7, я считаю, что теперь это основная библиотека csv в 1.9, используя это:
table = FasterCSV.read(result_file.to_file.path, { :headers => true, :col_sep => "\t", :skip_blanks => true })
unless table.empty?
header_arry = Array.new
table.headers.each do |h|
#your header logic, e.g.
# if h.downcase.include? 'pos'
# header_arry << 'position'
# end
# simplest case here
header_arry << h.downcase
#which produces an array of column names called header_arry
end
rows = table.to_a
rows.delete_at(0)
rows.each do |row|
#convert to hash using the column names
hash = Hash[header_arry.zip(row)]
# do something with the row hash
end
end
обновление
Проверьте драгоценный камень "smarter_csv"https://github.com/tilo/smarter_csv/ ; он имеет несколько интересных функций для создания хэшей из данных CSV.
Предыдущий Ответ
вот как я бы это сделал (по пути я конвертирую "массивы массивов", которые возвращаются CSV.чтение или CSV.разберите, в "массивы хэшей"... это делает данные более похожими на данные ActiveRecord, и немного легче обрабатывать этот способ позже на..
require 'csv'
def process(csv_array) # makes arrays of hashes out of CSV's arrays of arrays
result = []
return result if csv_array.nil? || csv_array.empty?
headerA = csv_array.shift # remove first array with headers from array returned by CSV
headerA.map!{|x| x.downcase.to_sym } # make symbols out of the CSV headers
csv_array.each do |row| # convert each data row into a hash, given the CSV headers
result << Hash[ headerA.zip(row) ] # you could use HashWithIndifferentAccess here instead of Hash
end
return result
end
# reading in the CSV data is now just one line:
csv_data = process( CSV.read( filename , { :col_sep => "\t"}) )
=> [{:id=>"1", :name=>"Mike", :car=>"Honda"},
{:id=>"2", :name=>"Adam", :car=>"Jim"}]
теперь вы можете обрабатывать данные такой:
csv_data.each do |hash|
# ...
end
Читайте также:
http://as.rubyonrails.org/classes/HashWithIndifferentAccess.html
http://api.rubyonrails.org/classes/ActiveSupport/HashWithIndifferentAccess.html
я использовал простой способ анализа данных csv. Здесь разделители табуляция, пробел, запятая или точка с запятой. Он возвращает массив полей.
row_data = File.new("your_file.csv").read
row_data = row_data.split(/[ ,;\s]/).reject(&:empty?)