Come faccio a creare una copia di alcune colonne di un file CSV in Ruby con dati diversi in una colonna?


85

Ho un file CSV chiamato "A.csv". Devo generare un nuovo file CSV denominato "B.csv" con i dati di "A.csv".

Userò un sottoinsieme di colonne da "A.csv" e dovrò aggiornare i valori di una colonna a nuovi valori in "B.csv". Infine, userò questi dati da B.csv per convalidare su un database.

  1. Come creo un nuovo file CSV?
  2. Come faccio a copiare i dati delle colonne richieste da A.csv a "B.csv"?
  3. Come aggiungo i valori per una particolare colonna?

Sono nuovo in Ruby, ma sono in grado di leggere CSV per ottenere un array o un hash.


2
Mancano informazioni di base, come mostrarci il tuo impegno per risolvere il problema. Queste informazioni sono nella documentazione CSV. Leggi " Come chiedere " e " esempio riproducibile minimo ".
Tin Man

Possibile duplicato dell'array
phunehehe

Risposte:


193

Come ha sottolineato mikeb, ci sono i documenti - http://ruby-doc.org/stdlib-1.9.3/libdoc/csv/rdoc/CSV.html - Oppure puoi seguire gli esempi seguenti (tutti sono testati e Lavorando):

Per creare un nuovo file:

In questo file avremo due righe, una riga di intestazione e una riga di dati, CSV molto semplice:

require "csv"
CSV.open("file.csv", "wb") do |csv|
  csv << ["animal", "count", "price"]
  csv << ["fox", "1", "$90.00"]
end

risultato, un file chiamato "file.csv" con quanto segue:

animal,count,price
fox,1,$90.00

Come aggiungere dati a un CSV

Quasi la stessa formula di sopra solo invece di utilizzare la modalità "wb", useremo la modalità "a +". Per ulteriori informazioni su questi, vedere questa risposta di overflow dello stack: Quali sono le modalità e le opzioni di Ruby File.open?

CSV.open("file.csv", "a+") do |csv|
  csv << ["cow", "3","2500"]
end

Ora quando apriamo il nostro file.csv abbiamo:

animal,count,price
fox,1,$90.00
cow,3,2500

Leggi dal nostro file CSV

Ora sai come copiare e scrivere su un file, per leggere un CSV e quindi afferrare i dati per la manipolazione che fai:

CSV.foreach("file.csv") do |row|
  puts row #first row would be ["animal", "count", "price"] - etc.
end

Ovviamente, questo è come uno dei cento modi diversi in cui puoi estrarre informazioni da un CSV usando questa gemma. Per maggiori informazioni, suggerisco di visitare la documentazione ora che hai un primer: http://ruby-doc.org/stdlib-1.9.3/libdoc/csv/rdoc/CSV.html


E se volessi aprire senza scrivere subito? Semplicemente non usi il blocco?
Donato

grazie per il codice in grado di copiare e incollare! - troppo pigro per scriverlo.
DominikAngerer

Questo copre la creazione di un nuovo CSV, ma poi entra nelle informazioni sull'aggiunta e la lettura di intere righe piuttosto che indirizzare la richiesta di copiare un sottoinsieme delle colonne disponibili e alterare o aggiungere ai loro valori. Ho lo stesso tipo di progetto dell'OP e non sono stato aiutato dalla documentazione o da questa risposta, quindi spero di poter tornare qui per fornire una risposta più specifica una volta che l'avrò capito.
Tyler James Young


0

Probabilmente vorrai usare CSV::parse per aiutare Ruby a capire il tuo CSV come la tabella di dati che è e consentire un facile accesso ai valori tramite intestazione.

Purtroppo, la documentazione disponibile sul CSV::parsemetodo non rende molto chiaro come utilizzarlo effettivamente per questo scopo.

Avevo un compito simile e sono stato aiutato molto di più da How to Read & Parse CSV Files With Ruby su rubyguides.com che dalla documentazione della classe CSV o dalle risposte che puntano ad esso da qui.

Consiglio di leggere quella pagina nella sua interezza. La parte cruciale consiste nel trasformare un dato CSV in un CSV::Tableoggetto usando:

table = CSV.parse(File.read("cats.csv"), headers: true)

Ora c'è la documentazione sulla CSV::Tableclasse , ma ancora una volta potresti essere aiutato di più dagli esempi chiari sulla pagina rubyguides.com. Una cosa che evidenzierò è che quando dici .parsedi aspettarti le intestazioni, la tabella risultante tratterà la prima riga di dati come riga [0].

Probabilmente sarai particolarmente interessato al .by_colmetodo disponibile per il tuo nuovo Tableoggetto. Ciò consentirà di iterare attraverso diverse posizioni dell'indice di colonna nell'input e / o nell'output e copiarlo dall'uno all'altro o aggiungere un nuovo valore all'output. Se riesco a farlo funzionare, tornerò e posterò un esempio.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.