2010-12-13 9 views
0

Étant relativement nouveau à Ruby, j'essaie de comprendre comment faire ce qui suit en utilisant FasterCSV: Ouvrez un fichier CSV, choisissez une colonne par son en-tête, dans cette colonne seulement remplacer tous occurrences de chaîne x avec y, écrivez le nouveau fichier dans STDOUT. Le code suivant fonctionne presque:Remplacer du texte dans une colonne CSV en utilisant FasterCSV

filename = ARGV[0] 
csv = FCSV.read(filename, :headers => true, :header_converters => :symbol, :return_headers => true, :encoding => 'u') 
mycol = csv[:mycol] 
# construct a mycol_new by iterating over mycol and doing some string replacement 
puts csv[:mycol][0] # produces "MyCol" as expected 
puts mycol_new[0] # produces "MyCol" as expected 
csv[:mycol] = mycol_new 
puts csv[:mycol][0] # produces "mycol" while "MyCol" is expected 
csv.each do |r| 
    puts r.to_csv(:force_quotes => true) 
end 

Le seul problème est qu'il ya une conversion d'en-tête où je ne m'y attendais pas. Si l'en-tête de la colonne choisie est "MyCol" avant la substitution des colonnes dans la table csv c'est "mycol" après (voir les commentaires dans le code). Pourquoi cela arrive-t-il? Et comment l'éviter? Merci.

Répondre

4

Vous pouvez modifier certaines choses dans la ligne d'initialisation. Changer:

csv = FCSV.read(filename, :headers => true, :return_headers => true, :encoding => 'u') 

à:

csv = FCSV.read(filename, :headers => true, :encoding => 'u') 

J'utilise CSV, qui est FasterCSV que cela fait partie de Ruby 1.9. Cela va créer un fichier CSV dans le répertoire courant appelé « temp.csv » avec un champ modifié « FName »:

require 'csv' 

data = "ID,FName,LName\n1,mickey,mouse\n2,minnie,mouse\n3,donald,duck\n" 

# read and parse the data 
csv_in = CSV.new(data, :headers => true) 

# open the temp file 
CSV.open('./temp.csv', 'w') do |csv_out| 

    # output the headers embedded in the object, then rewind to the start of the list 
    csv_out << csv_in.first.headers 
    csv_in.rewind 

    # loop over the rows 
    csv_in.each do |row| 

    # munge the first name 
    if (row['FName']['mi']) 
     row['FName'] = row['FName'][1 .. -1] << '-' << row['FName'][0] << 'ay' 
    end 

    # output the record 
    csv_out << row.fields 
    end 
end 

La sortie ressemble à:

ID,FName,LName 
1,ickey-may,mouse 
2,innie-may,mouse 
3,donald,duck 
+0

Merci Greg. Lorsque vous écrivez la chose qui aide est de manipuler la colonne de choix directement au lieu de construire une nouvelle colonne et ensuite essayer de remplacer la colonne existante par la nouvelle (voir le code ci-dessous). – Stefan

3

Il est possible de manipuler le choix colonne directement dans l'objet FasterCSV au lieu de créer une nouvelle colonne, puis en essayant de remplacer l'ancien par le nouveau.

Questions connexes