Ruby ne peut pas analyser un fichier CSV:: CSV:: MalformedCSVError (citation illégale à la ligne 1.)

Ubuntu 12.04 LTS

Ruby ruby 1.9.3 dev (2011-09-23 revision 33323) [i686-linux]

Rails 3.2.9

voici le contenu de mon fichier CSV reçu:

"date/time","settlement id","type","order id","sku","description","quantity","marketplace","fulfillment","order city","order state","order postal","product sales","shipping credits","gift wrap credits","promotional rebates","sales tax collected","selling fees","fba fees","other transaction fees","other","total"
"Mar 1, 2013 12:03:54 AM PST","5481545091","Order","108-0938567-7009852","ALS2GL36LED","Solar Two Directional 36 Bright White LED Security Flood Light with Motion Activated Sensor","1","amazon.com","Amazon","Pasadena","CA","91104-1056","43.00","3.25","0","-3.25","0","-6.45","-3.75","0","0","32.80"

Cependant lorsque j'essaie d'analyser le fichier CSV, j'obtiens l'erreur:

1.9.3dev :016 > options = { col_sep: ",", quote_char:'"' }
=> {:col_sep=>",", :quote_char=>"""} 

1.9.3dev :022 > CSV.foreach("/tmp/my_data.csv", options) { |row| puts row }
CSV::MalformedCSVError: Illegal quoting in line 1.
    from /home/jigneshgohel/.rvm/rubies/ruby-1.9.3-rc1/lib/ruby/1.9.1/csv.rb:1925:in `block (2 levels) in shift'
    from /home/jigneshgohel/.rvm/rubies/ruby-1.9.3-rc1/lib/ruby/1.9.1/csv.rb:1887:in `each'
    from /home/jigneshgohel/.rvm/rubies/ruby-1.9.3-rc1/lib/ruby/1.9.1/csv.rb:1887:in `block in shift'
    from /home/jigneshgohel/.rvm/rubies/ruby-1.9.3-rc1/lib/ruby/1.9.1/csv.rb:1849:in `loop'
    from /home/jigneshgohel/.rvm/rubies/ruby-1.9.3-rc1/lib/ruby/1.9.1/csv.rb:1849:in `shift'
    from /home/jigneshgohel/.rvm/rubies/ruby-1.9.3-rc1/lib/ruby/1.9.1/csv.rb:1791:in `each'
    from /home/jigneshgohel/.rvm/rubies/ruby-1.9.3-rc1/lib/ruby/1.9.1/csv.rb:1208:in `block in foreach'
    from /home/jigneshgohel/.rvm/rubies/ruby-1.9.3-rc1/lib/ruby/1.9.1/csv.rb:1354:in `open'
    from /home/jigneshgohel/.rvm/rubies/ruby-1.9.3-rc1/lib/ruby/1.9.1/csv.rb:1207:in `foreach'
    from (irb):22
    from /home/jigneshgohel/.rvm/rubies/ruby-1.9.3-rc1/bin/irb:16:in `<main>'

puis j'ai essayé de simplifier les données i.e.

"name","age","email"
"jignesh","30","jignesh@example.com"

cependant j'ai toujours la même chose erreur:

      1.9.3dev :023 > CSV.foreach("/tmp/my_data.csv", options) { |row| puts row }
  CSV::MalformedCSVError: Illegal quoting in line 1.
      from /home/jigneshgohel/.rvm/rubies/ruby-1.9.3-rc1/lib/ruby/1.9.1/csv.rb:1925:in `block (2 levels) in shift'
      from /home/jigneshgohel/.rvm/rubies/ruby-1.9.3-rc1/lib/ruby/1.9.1/csv.rb:1887:in `each'
      from /home/jigneshgohel/.rvm/rubies/ruby-1.9.3-rc1/lib/ruby/1.9.1/csv.rb:1887:in `block in shift'
      from /home/jigneshgohel/.rvm/rubies/ruby-1.9.3-rc1/lib/ruby/1.9.1/csv.rb:1849:in `loop'
      from /home/jigneshgohel/.rvm/rubies/ruby-1.9.3-rc1/lib/ruby/1.9.1/csv.rb:1849:in `shift'
      from /home/jigneshgohel/.rvm/rubies/ruby-1.9.3-rc1/lib/ruby/1.9.1/csv.rb:1791:in `each'
      from /home/jigneshgohel/.rvm/rubies/ruby-1.9.3-rc1/lib/ruby/1.9.1/csv.rb:1208:in `block in foreach'
      from /home/jigneshgohel/.rvm/rubies/ruby-1.9.3-rc1/lib/ruby/1.9.1/csv.rb:1354:in `open'
      from /home/jigneshgohel/.rvm/rubies/ruby-1.9.3-rc1/lib/ruby/1.9.1/csv.rb:1207:in `foreach'
      from (irb):23
      from /home/jigneshgohel/.rvm/rubies/ruby-1.9.3-rc1/bin/irb:16:in `<main>'

Encore une fois j'ai essayé de simplifier les données comme ceci:

name,age,email
jignesh,30,jignesh@example.com

et ça fonctionne.Voir le résultat ci-dessous:

  1.9.3dev :024 > CSV.foreach("/tmp/my_data.csv") { |row| puts row }
  name
  age
  email
  jignesh
  30
  jignesh@example.com
   => nil 

mais je vais recevoir les fichiers CSV ayant Cité des données, donc supprimer des guillemets n'est pas la solution que je recherche.Je suis incapable de comprendre ce qui est à l'origine de l'erreur: CSV:: MalformedCSVError: citation illégale à la ligne 1. dans mes exemples précédents.

j'ai vérifié que dans le CSV il ne sont pas des espaces de tête / de queue en activant "Show whitespace characters" et "Show Line Endings" dans mon éditeur de texte.J'ai aussi vérifié l'encodage en utilisant ce qui suit.

  1.9.3dev :026 > File.open("/tmp/my_data.csv").read.encoding
  => #<Encoding:UTF-8> 

Note: j'ai essayé D'utiliser CSV.lire aussi, mais même erreur avec cette méthode.

quelqu'un Peut-il m'aider à sortir du problème et de me faire comprendre où il va mal?

=====================

je viens de trouver le post suivant à: http://www.ruby-forum.com/topic/448070 et essayé suivante:

  file_data = file.read
  file_data.gsub!('"', "'")
  arr_of_arrs = CSV.parse(file_data)

  arr_of_arrs.each do |arr|
    Rails.logger.debug "=======#{arr}"
  end

et a obtenu le résultat suivant:

   =======["xEFxBBxBF'date/time'", "'settlement id'", "'type'", "'order id'", "'sku'", "'description'", "'quantity'", "'marketplace'", "'fulfillment'", "'order city'", "'order state'", "'order postal'", "'product sales'", "'shipping credits'", "'gift wrap credits'", "'promotional rebates'", "'sales tax collected'", "'selling fees'", "'fba fees'", "'other transaction fees'", "'other'", "'total'"]
    =======["'Mar 1", " 2013 12:03:54 AM PST'", "'5481545091'", "'Order'", "'108-0938567-7009852'", "'ALS2GL36LED'", "'Solar Two Directional 36 Bright White LED Security Flood Light with Motion Activated Sensor'", "'1'", "'amazon.com'", "'Amazon'", "'Pasadena'", "'CA'", "'91104-1056'", "'43.00'", "'3.25'", "'0'", "'-3.25'", "'0'", "'-6.45'", "'-3.75'", "'0'", "'0'", "'32.80'"]

qui a foiré la lecture des données correctement comme la valeur par défaut col_sep utilisé est un caractère virgule. Cependant j'ai essayé d'utiliser quote_char option de ce genre:

  arr_of_arrs = CSV.parse(file_data, :quote_char => "'")

mais ça c'est terminé, le message d'erreur suivant:

   CSV::MalformedCSVError (Illegal quoting in line 1.):

Merci, Jignesh

18
demandé sur Jiggneshh Gohel 2013-05-27 16:04:06

5 réponses

quote_chars = %w(" | ~ ^ & *)
begin
  @report = CSV.read(csv_file, headers: :first_row, quote_char: quote_chars.shift)
rescue CSV::MalformedCSVError
  quote_chars.empty? ? raise : retry 
end

ce n'est pas parfait, mais il fonctionne la plupart du temps.

N.B. CSV.parse prend les mêmes paramètres que CSV.read, donc soit un fichier ou des données de la mémoire peut être utilisé

21
répondu Vadym Tyemirov 2013-09-27 04:40:12

Anand, merci pour la suggestion d'encodage. Cela a résolu le problème des citations illégales pour moi.

Note: Si vous voulez que l'itérateur saute sur la ligne d'en-tête ajouter headers: :first_row, comme ceci:

CSV.foreach("test.csv", encoding: "bom|utf-8", headers: :first_row)
12
répondu theUtherSide 2016-05-18 07:19:06

j'ai juste eu un problème comme celui-ci et j'ai découvert que CSV n'aime pas les espaces entre le col-sep et le caractère de citation. Une fois que j'ai enlevé ceux tout s'est bien passé. J'ai donc eu:

12,  "N",  12, "Pacific/Majuro"

mais une fois que j'ai remplacé les espaces par

.gsub(/,\s+\"/,',\"')

entraînant

12,"N",  12,"Pacific/Majuro"

tout s'est bien passé.

11
répondu user2391694 2013-10-18 18:30:07

j'ai eu un problème avec le caractère de la marque qui lançait cette erreur.

le caractère de la marque se traduit par\"! en UTF-8, c'est donc le symbole de citation ouvert qui lançait l'erreur. J'ai donc fait ceci:

.gsub!("\"!", "")

et puis j'ai essayé de créer mon objet CSV et ça a bien fonctionné.

1
répondu Elena Tanasoiu 2016-02-25 12:11:25

Essayez cette astuce:

  1. ouvrez votre fichier CSV dans un éditeur de texte
  2. sélectionnez l'ensemble du fichier et copiez-le
  3. Ouvrir un nouveau fichier texte
  4. coller les données CSV dans le nouveau fichier et enregistrer le nouveau fichier
  5. Importez votre nouveau fichier CSV
-3
répondu Ravindra 2014-09-26 19:24:19