¿Cómo creo una copia de algunas columnas de un archivo CSV en Ruby con diferentes datos en una columna?

84

Tengo un archivo CSV llamado "A.csv". Necesito generar un nuevo archivo CSV llamado "B.csv" con datos de "A.csv".

Usaré un subconjunto de columnas de "A.csv" y tendré que actualizar los valores de una columna a nuevos valores en "B.csv". En última instancia, usaré estos datos de B.csv para validarlos con una base de datos.

  1. ¿Cómo creo un nuevo archivo CSV?
  2. ¿Cómo copio los datos de las columnas requeridas de A.csv a "B.csv"?
  3. ¿Cómo agrego valores para una columna en particular?

Soy nuevo en Ruby, pero puedo leer CSV para obtener una matriz o hash.

usuario1718712
fuente
2
Esto carece de información básica, como mostrarnos su esfuerzo para resolver el problema. Esta información se encuentra en la documentación CSV. Lea " Cómo preguntar " y " Ejemplo mínimo reproducible ".
The Tin Man
Posible duplicado de la matriz
phunehehe

Respuestas:

191

Como señaló mikeb, existen los documentos: http://ruby-doc.org/stdlib-1.9.3/libdoc/csv/rdoc/CSV.html - O puede seguir los ejemplos a continuación (todos están probados y trabajando):

Para crear un nuevo archivo:

En este archivo tendremos dos filas, una fila de encabezado y una fila de datos, CSV muy simple:

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

resultado, un archivo llamado "file.csv" con lo siguiente:

animal,count,price
fox,1,$90.00

Cómo agregar datos a un CSV

Casi la misma fórmula que la anterior, pero en lugar de usar el modo "wb", usaremos el modo "a +". Para obtener más información sobre estos, consulte esta respuesta de desbordamiento de pila: ¿Cuáles son los modos y opciones de Ruby File.open?

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

Ahora, cuando abrimos nuestro archivo.csv tenemos:

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

Leer de nuestro archivo CSV

Ahora sabe cómo copiar y escribir en un archivo, leer un CSV y, por lo tanto, tomar los datos para manipularlos:

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

Por supuesto, esta es una de las cientos de formas diferentes en las que puede extraer información de un CSV usando esta joya. Para obtener más información, sugiero que visite los documentos ahora que tiene un manual: http://ruby-doc.org/stdlib-1.9.3/libdoc/csv/rdoc/CSV.html

newUserNameHere
fuente
¿Qué pasa si quiero abrir sin escribir de inmediato? ¿Simplemente no uses el bloque?
Donato
¡Gracias por copiar y pegar el código! - Demasiado perezoso para escribirlo.
DominikAngerer
Esto cubre la creación de un nuevo CSV, pero luego incluye información sobre cómo agregar y leer filas completas en lugar de abordar la solicitud de copiar un subconjunto de los coumns disponibles y modificar o agregar sus valores. Tengo el mismo tipo de proyecto que el OP y no me ayudó la documentación o esta respuesta, así que espero poder volver aquí para proporcionar una respuesta más específica una vez que lo averigüe.
Tyler James Young
4

¿Has visto la clase CSV de Ruby? Parece bastante completo. Compruébelo aquí: http://ruby-doc.org/stdlib-1.9.3/libdoc/csv/rdoc/CSV.html

MikeB
fuente
1
Gracias por el enlace. Lo estaría refiriendo. ¿Puedo editar el archivo csv a través de ruby? Quiero decir, ¿puedo actualizar los valores de una columna en csv? luego obtiene hash de las columnas requeridas?
user1718712
0

Probablemente querrá usarlo CSV::parsepara ayudar a Ruby a entender su CSV como la tabla de datos que es y permitir un fácil acceso a los valores por encabezado.

Desafortunadamente, la documentaciónCSV::parse disponible sobre el método no deja muy claro cómo usarlo para este propósito.

Tuve una tarea similar y me ayudó mucho más Cómo leer y analizar archivos CSV con Ruby en rubyguides.com que la documentación de la clase CSV o las respuestas que apuntan a ella desde aquí.

Recomiendo leer esa página en su totalidad. La parte crucial es transformar un CSV dado en un CSV::Tableobjeto usando:

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

Ahora hay documentación sobre la CSV::Tableclase , pero nuevamente los ejemplos claros en la página rubyguides.com pueden ayudarlo más. Una cosa que destacaré es que cuando dices .parseque esperes encabezados, la tabla resultante tratará la primera fila de datos como una fila [0].

Probablemente le interese especialmente el .by_colmétodo disponible para su nuevo Tableobjeto. Esto le permitirá iterar a través de diferentes posiciones de índice de columna en la entrada y / o salida y copiar de una a otra o agregar un nuevo valor a la salida. Si consigo que funcione, volveré y publicaré un ejemplo.

Tyler James Young
fuente