用于将CSV转换为JSON的Ruby脚本

时间:2014-10-16 10:33:12

标签: ruby json csv

#!/usr/bin/env ruby
require 'rubygems'
require 'json'
require 'csv'
def is_int(str)
return !!(str =~ /^[-+]?[1-9]([0-9]*)?$/)
end

lines = CSV.open(ARGV[0],{:col_sep => "\|"}).readlines
keys = lines.delete lines.first

File.open(ARGV[1], "w") do |f|
data = lines.map do |values|
is_int(values) ? values.to_i : values.to_s
Hash[keys.zip(values)]
end
f.puts JSON.pretty_generate(data)
end

我有这个Ruby脚本用于解析csv文件并以JSON格式打印第二个文件。

我对Ruby不是很好,但是我喜欢修改它   - 阅读csv文件
  - 对于任何一行(除了第一个是标题)
  - 创建一个file.json,其中文件的名称是行的第二个字段

例如:
csv文件:

ID|NAME|SURNAME|TELEPHONE
01|Jhon|Smith|123456
02|Steve|Brown|654321

文件jhon.json的输出:

[
  {
    "ID": "01",
    "NAME": "Jhon",
    "SURNAME": "Smith",
    "TELEPHONE": "123456",
  },
]

有人可以帮助我吗?

3 个答案:

答案 0 :(得分:2)

CSV库可以为您处理大部分处理:

require 'csv'
require 'json'

options = { col_sep: '|', converters: :numeric, headers: true }

CSV.foreach(ARGV[0], options) do |row|
  filename = "#{row['NAME'].downcase}.json"
  File.open(filename, 'w') { |f| f << JSON.pretty_generate(row.to_hash) }
end

传递converters: :numeric会将数字字段转换为数字类型(IntegerFloat)。

headers: true选项允许您按名称访问字段(例如row['NAME'])并将行转换为哈希值。

答案 1 :(得分:1)

你接近解决方案,但让我们重新格式化并简化它

lines = CSV.open(ARGV[0],{:col_sep => "\|"}).readlines
# remove first entry of the lines array 
keys = lines.shift  

lines.each do |values|
     # convert the line into a hash and transform string into int
     hash=Hash[keys.zip(values.map{|val| is_int(val) ? val.to_i : val}) ]

     # Write a file with the hash results
     File.open("#{hash['NAME']}.json", "w") do |f|
        f.write JSON.pretty_generate [hash]
     end
end

在这里,您将为要保存的每一行打开一个新文件

答案 2 :(得分:0)

tomsoft的解决方案看起来更好,但无论如何这都是我的:

 output = []
 lines = CSV.open(ARGV[0],{:col_sep => "\|"}).readlines
 headers = lines.shift
 lines.each_with_index.map do |line, index| 
   output << Hash[*line.each_with_index.map {|col, index| [headers[index],is_int(col) ?    col.to_i : col]}.flatten]
 end
 File.open(ARGV[1], "w") do |f|
   f << output
 end