【问题标题】:Ruby Script for converting CSV to JSON用于将 CSV 转换为 JSON 的 Ruby 脚本
【发布时间】:2014-10-16 10:33:12
【问题描述】:
#!/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",
  },
]

有人可以帮我吗?

【问题讨论】:

标签: ruby json csv


【解决方案1】:

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'])并将行转换为哈希。

【讨论】:

    【解决方案2】:

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

    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
    

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

    【讨论】:

    • 非常感谢 tomsoft!
    • 在将块传递给File.open 时,您不必显式关闭文件。
    • 写,我正在删除它
    【解决方案3】:

    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
    

    【讨论】:

      猜你喜欢
      • 2014-04-21
      • 1970-01-01
      • 1970-01-01
      • 2014-06-04
      • 1970-01-01
      • 1970-01-01
      • 2011-05-23
      • 2016-09-14
      • 2016-09-02
      相关资源
      最近更新 更多