2013-04-09 2 views
16

Je rencontre des problèmes pour écrire des colonnes dans un fichier CSV avec Ruby. Voici mon extrait de code.Comment écrire l'en-tête des colonnes dans un fichier csv avec Ruby?

calc = numerator/denominator.to_f 
data_out = "#{numerator}, #{denominator}, #{calc}" 
File.open('cdhu3_X.csv','a+') do|hdr| 
     hdr << ["numerator","denominator","calculation\n"] #< column header 
      hdr << "#{data_out}\n" 
end 

Le code ajoute les en-têtes de colonne à chaque ligne et j'en ai seulement besoin en haut de chaque colonne de données. J'ai cherché ici et d'autres endroits, mais je ne peux pas trouver une réponse claire à la façon dont c'est fait. Toute aide serait grandement appréciée.

Répondre

6

La manière la plus propre de le faire est d'ouvrir le fichier une fois, en mode 'w', d'écrire les en-têtes, puis d'écrire les données.

S'il existe une raison technique qui ne peut pas le faire (par exemple, les données ne sont pas disponibles en une seule fois), vous pouvez utiliser la méthode IO#tell sur le fichier pour renvoyer la position actuelle du fichier. Lorsque vous ouvrez le fichier pour annexant, la position est réglée à la fin du fichier, donc si la position actuelle du fichier est égal à zéro, le fichier a été nouvellement créé et n'a pas les en-têtes:

File.open('cdhu3_X.csv', 'a+') do |hdr| 
    if hdr.tell() == 0 # file is empty, so write header 
    hdr << "numerator, denominator, calculation\n" 
    end 
    hdr << "#{data_out}\n" 
end 
+0

Salut, cela a fonctionné. Je vous remercie. Jfleck – Joe

38

Je recommande à utiliser le CSV bibliothèque à la place:

require 'csv' 

CSV.open('test.csv','w', 
    :write_headers=> true, 
    :headers => ["numerator","denominator","calculation"] #< column header 
) do|hdr| 
    1.upto(12){|numerator| 
    1.upto(12){ |denominator| 
     data_out = [numerator, denominator, numerator/denominator.to_f] 
     hdr << data_out 
    } 
    } 
end 

Si vous ne pouvez pas utiliser l'option w et vous avez vraiment besoin a+ (par exemple, les données ne sont pas disponibles à la fois), alors vous pouvez essayer l'astuce suivante :

require 'csv' 

column_header = ["numerator","denominator","calculation"] 
1.upto(12){|numerator| 
    1.upto(12){ |denominator| 
    CSV.open('test.csv','a+', 
     :write_headers=> true, 
     :headers => column_header 
    ) do|hdr| 
      column_header = nil #No header after first insertion 
      data_out = [numerator, denominator, numerator/denominator.to_f] 
      hdr << data_out 
     end 
    } 
} 
2

La meilleure façon de gérer le fichier csv est d'utiliser le module CSV de Ruby.

J'ai eu le même problème après avoir lu le code CSV Je suis tombé sur cette solution que je trouve la plus efficace.

headers = ['col1','col2','col3'] 

CSV.open(file_path, 'a+', {force_quotes: true}) do |csv| 
    csv << headers if csv.count.eql? 0 # csv.count method gives number of lines in file if zero insert headers 
end 
+1

Comment changer les en-têtes d'origine après l'insertion de certaines données? Dites que je peux avoir des colonnes supplémentaires, mais que je saurais seulement après que les données ont été remplies? J'ai essayé csv.headers.push mais ne met pas à jour les en-têtes réels dans le fichier qu'il sort. Merci – scanales

Questions connexes