Voglio convertire il file .json nel file .csv usando ruby. Piacere mi aiuta a farlo.Converti .json in .csv in ruby
Proporre anche qualsiasi strumento per raggiungere questo obiettivo.
Voglio convertire il file .json nel file .csv usando ruby. Piacere mi aiuta a farlo.Converti .json in .csv in ruby
Proporre anche qualsiasi strumento per raggiungere questo obiettivo.
provare qualcosa di simile:
require 'csv'
require 'json'
csv_string = CSV.generate do |csv|
JSON.parse(File.open("foo.json").read).each do |hash|
csv << hash.values
end
end
puts csv_string
Bello e semplice. Ricordare che questo non tiene conto della nidificazione e presuppone che tutti gli oggetti nell'elenco siano uguali. – SirLenz0rlot
Per scrivere in realtà nel file ...
require 'csv'
require 'json'
CSV.open("your_csv.csv", "w") do |csv| #open new file for write
JSON.parse(File.open("your_json.json").read).each do |hash| #open json to parse
csv << hash.values #write value to file
end
end
Penso che il modo easies per convertire il JSON in formato CSV in Ruby è json2csv utilizza gemma rubino.
PS: Potrei essere di parte perché ne sono autore.
L'esecuzione del comando
json2csv convert data/sample.json
file di input
In questo caso particolare si convertirà seguente JSON:
cat data/sample.json
{
"12345": {
"Firstname": "Joe",
"Lastname": "Doe",
"Address": {
"Street": "#2140 Taylor Street, 94133",
"City": "San Francisco",
"Details": {
"note": "Pool available"
}
}
},
"45678": {
"Firstname": "Jack",
"Lastname": "Plumber",
"Address": {
"Street": "#111 Sutter St, 94104",
"City": "San Francisco",
"Details": {
"note": "Korean Deli near to main entrance"
}
}
}
uscita
cat data/sample.json.csv
id,Firstname,Lastname,Address.Street,Address.City,Address.Details.note
12345,Joe,Doe,"#2140 Taylor Street, 94133",San Francisco,Pool available
45678,Jack,Plumber,"#111 Sutter St, 94104",San Francisco,Korean Deli near to main entrance
Ciao @korCZis - Ho provato la tua gemma e ho ottenuto quanto segue: json2csv convert errors.json NameError: variabile locale non definita o metodo 'errors 'per main: Oggetto da (irb): 3 da/usr/local/opt /rbenv/versions/2.1.5/bin/irb:11:in '
Puoi pubblicare lo stack stack completo o scrivermi un'email? [email protected] – korCZis
sì, fammi riprovare .... https: //github.com/korczis/json2csv/issues/2 – Angela
Sulla base @Alex's answer ma aggiungendo intestazioni csv e esempio di test.
# utils.rb
require "csv"
module Utils
def self.array_of_hashes_to_csv(array_of_hashes)
CSV.generate do |csv|
csv << array_of_hashes.first.keys
array_of_hashes.each { |hash| csv << hash.values }
end
end
end
# utils_test.rb
class UtilsTest < MiniTest::Unit::TestCase
def test_array_of_hashes_to_csv
array_of_hashes = [
{ :key1 => "value1", :key2 => "value2" },
{ :key1 => "value3", :key2 => "value4" }
]
expected_result = "key1,key2\nvalue1,value2\nvalue3,value4\n"
assert_equal(expected_result, Utils.array_of_hashes_to_csv(array_of_hashes))
end
end
Codice rubino per convertire da json a csv.
Gestisce gli array convertendoli in stringhe con doppie virgolette.
#json-to-csv.rb
require 'json'
require 'csv'
file = File.read('./input.json')
hash = JSON.parse(file)
CSV.open('./output.csv', 'w') do |csv|
headers = hash.first.keys
csv << headers
hash.each do |item|
values = item.values
printable_values = Array.new
values.each do |value|
printable_values << value.to_s.gsub(/\[|\]/,'').gsub(/"/,'\'')
end
csv << printable_values
end
end
Edit:
Questa funzionalità descritte di seguito è ora disponibile come gem. Dopo aver installato con gem install json_converter
, il seguente frammento può essere utilizzato per generare un file CSV da una stringa valida JSON o un oggetto:
require 'json_converter'
json_converter= JsonConverter.new
# Assume json is a valid JSON string or object
csv = json_converter.generate_csv json
risposta originale:
Se i dati JSON è relativamente semplice (senza nidificazione o matrici), la risposta di Alex è probabilmente il modo più pulito di gestire questo problema.
Tuttavia, se si fa necessità di prendere gli array e gli oggetti nidificati in considerazione, ho tentato di porto un web version di un tale convertitore a Ruby. Può essere trovato here. I metodi che gestiscono l'effettiva ristrutturazione dei dati sono array_from
e flatten
.
Il metodo array_from
tenta di identificare l'aspetto di una "riga" di dati per un determinato set di dati. Non è perfetto e potresti voler modificare questa parte per set di dati diversi.
# Attempt to identify what a "row" should look like
def array_from(json)
queue, next_item = [], json
while !next_item.nil?
return next_item if next_item.is_a? Array
if next_item.is_a? Hash
next_item.each do |k, v|
queue.push next_item[k]
end
end
next_item = queue.shift
end
return [json]
end
Procedimento flatten
ricorsivamente itera l'oggetto JSON (s), e genera un oggetto che rappresenta intestazioni e valori. Se un oggetto è nidificato, l'intestazione per la sua colonna sarà preceduta dal suo codice genitore (parentesi), delimitato dal carattere /
.
# The path argument is used to construct header columns for nested elements
def flatten(object, path='')
scalars = [String, Integer, Fixnum, FalseClass, TrueClass]
columns = {}
if [Hash, Array].include? object.class
object.each do |k, v|
new_columns = flatten(v, "#{path}#{k}/") if object.class == Hash
new_columns = flatten(k, "#{path}#{k}/") if object.class == Array
columns = columns.merge new_columns
end
return columns
elsif scalars.include? object.class
# Remove trailing slash from path
end_path = path[0, path.length - 1]
columns[end_path] = object
return columns
else
return {}
end
end
Se ci sono null
valori nella originale JSON, è necessario convertire questi per qualcosa di diverso da nil
prima di tentare la conversione - ti generalmente finisce con righe irregolari, se non lo fai. Il metodo nils_to_strings
gestisce che:
# Recursively convert all nil values of a hash to empty strings
def nils_to_strings(hash)
hash.each_with_object({}) do |(k,v), object|
case v
when Hash
object[k] = nils_to_strings v
when nil
object[k] = ''
else
object[k] = v
end
end
end
Ecco un breve esempio di come questo possa essere utilizzato:
json = JSON.parse(File.open('in.json').read)
in_array = array_from json
in_array.map! { |x| nils_to_strings x }
out_array = []
in_array.each do |row|
out_array[out_array.length] = flatten row
end
headers_written = false
CSV.open('out.csv', 'w') do |csv|
out_array.each do |row|
csv << row.keys && headers_written = true if headers_written === false
csv << row.values
end
end
E, infine, ecco qualche esempio di input/output:
ingresso:
{
"Forms": [
{
"Form": {
"id": "x",
"version_id": "x",
"name": "x",
"category": "",
"subcategory": null,
"is_template": null,
"moderation_status": "x",
"display_status": "x",
"use_ssl": "x",
"modified": "x",
"Aggregate_metadata": {
"id": "x",
"response_count": "x",
"submitted_count": "x",
"saved_count": "x",
"unread_count": "x",
"dropout_rate": "x",
"average_completion_time": null,
"is_uptodate": "x"
}
},
"User": {
"username": "[email protected]"
}
},
{
"Form": {
"id": "x",
"version_id": "x",
"name": "x",
"category": "",
"subcategory": null,
"is_template": null,
"moderation_status": "x",
"display_status": "x",
"use_ssl": "x",
"modified": "x",
"Aggregate_metadata": {
"id": "x",
"response_count": "x",
"submitted_count": "x",
"saved_count": "x",
"unread_count": "x",
"dropout_rate": "x",
"average_completion_time": null,
"is_uptodate": "x"
}
},
"User": {
"username": "[email protected]"
}
}
]
}
Uscita:
Questo è handle intestazioni & nested json.
require 'csv'
require 'json'
@headers = []
file = File.open('file.json')
JSON.parse(file.read).each do |h|
h.keys.each do |key|
@headers << key
end
end
uniq_headers = @headers.uniq
file = File.open('file.json')
finalrow = []
JSON.parse(file.read).each do |h|
final = {}
@headers.each do |key2|
final[key2] = h[key2]
end
finalrow << final
end
CSV.open('output.csv' , 'w') do |csv|
csv << uniq_headers
finalrow.each do |deal|
csv << deal.values
end
end
Guardate questa: http://stackoverflow.com/questions/5357711/csv-to-json-ruby-script – WarHog
Avete un esempio per i dati JSON? JSON in sé può essere multidimensionale e csv è bidimensionale. – mliebelt