Como faço para criar uma cópia de algumas colunas de um arquivo CSV em Ruby com dados diferentes em uma coluna?

85

Tenho um arquivo CSV chamado "A.csv". Preciso gerar um novo arquivo CSV chamado "B.csv" com dados de "A.csv".

Usarei um subconjunto de colunas de "A.csv" e terei que atualizar os valores de uma coluna para novos valores em "B.csv". Por fim, usarei esses dados de B.csv para validar em um banco de dados.

  1. Como faço para criar um novo arquivo CSV?
  2. Como copio os dados das colunas obrigatórias de A.csv para "B.csv"?
  3. Como faço para anexar valores para uma coluna específica?

Sou novo em Ruby, mas consigo ler CSV para obter um array ou hash.

user1718712
fonte
2
Faltam informações básicas, como nos mostrar seu esforço para resolver o problema. Essas informações estão na documentação CSV. Leia " Como perguntar " e " exemplo reproduzível mínimo ".
o Tin Man
Possível duplicata da matriz
phunehehe 01 de

Respostas:

193

Como mikeb apontou, existem os documentos - http://ruby-doc.org/stdlib-1.9.3/libdoc/csv/rdoc/CSV.html - Ou você pode acompanhar os exemplos abaixo (todos são testados e trabalhando):

Para criar um novo arquivo:

Neste arquivo, teremos duas linhas, uma linha de cabeçalho e uma linha de dados, CSV muito simples:

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

resultado, um arquivo denominado "file.csv" com o seguinte:

animal,count,price
fox,1,$90.00

Como anexar dados a um CSV

Quase a mesma fórmula acima, em vez de usar o modo "wb", usaremos o modo "a +". Para obter mais informações sobre isso, consulte esta resposta para estouro de pilha: Quais são os modos e opções do Ruby File.open?

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

Agora, quando abrimos nosso arquivo.csv, temos:

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

Leia nosso arquivo CSV

Agora você sabe como copiar e gravar em um arquivo, ler um CSV e, portanto, obter os dados para manipulação que você acabou de fazer:

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

Claro, isso é como uma das centenas de maneiras diferentes de obter informações de um CSV usando esta joia. Para obter mais informações, sugiro visitar os documentos agora que você tem uma cartilha: http://ruby-doc.org/stdlib-1.9.3/libdoc/csv/rdoc/CSV.html

newUserNameHere
fonte
E se eu quiser abrir sem escrever imediatamente? Só não use o bloco?
Donato
obrigado pelo código capaz de copiar e colar! - com preguiça de escrever.
DominikAngerer
Isso cobre a criação de um novo CSV, mas depois entra em informações sobre como adicionar e ler linhas inteiras, em vez de abordar a solicitação para copiar um subconjunto dos itens disponíveis e alterar ou adicionar seus valores. Tenho o mesmo tipo de projeto do OP e não fui ajudado pela documentação ou por esta resposta, então espero poder voltar aqui para fornecer uma resposta mais específica assim que descobrir.
Tyler James Young
4

Você já viu a classe CSV do Ruby? Parece muito abrangente. Confira aqui: http://ruby-doc.org/stdlib-1.9.3/libdoc/csv/rdoc/CSV.html

MikeB
fonte
1
Obrigado pelo link. Eu estaria me referindo a isso. Posso editar o arquivo csv através do Ruby? Quer dizer, posso atualizar os valores de uma coluna em csv? mais tarde obter hash de apenas colunas obrigatórias?
user1718712
0

Você provavelmente vai querer usar CSV::parsepara ajudar Ruby a entender seu CSV como a tabela de dados que ele é e permitir acesso fácil aos valores por cabeçalho.

Infelizmente, a documentaçãoCSV::parse disponível sobre o método não deixa muito claro como realmente usá-lo para esse propósito.

Eu tive uma tarefa semelhante e fui ajudado muito mais por Como ler e analisar arquivos CSV com Ruby em rubyguides.com do que pela documentação da classe CSV ou pelas respostas apontando para ela daqui.

Recomendo a leitura dessa página na íntegra. A parte crucial é transformar um determinado CSV em um CSV::Tableobjeto usando:

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

Agora há documentação sobre a CSV::Tableclasse , mas novamente você pode ser ajudado mais pelos exemplos claros na página rubyguides.com. Algo que destacarei é que, quando você disser .parsepara esperar cabeçalhos, a tabela resultante tratará a primeira linha de dados como uma linha [0].

Você provavelmente estará especialmente interessado no .by_colmétodo disponível para seu novo Tableobjeto. Isso permitirá que você itere através de diferentes posições de índice de coluna na entrada e / ou saída e copie de uma para a outra ou adicione um novo valor à saída. Se eu conseguir fazer funcionar, voltarei e postarei um exemplo.

Tyler James Young
fonte