it-swarm.com.de

Ruby kann eine CSV-Datei nicht analysieren: CSV :: MalformedCSVError (unzulässige Anführungszeichen in Zeile 1)

Ubuntu 12.04 LTS

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

Rails 3.2.9

Folgendes ist der Inhalt meiner erhaltenen CSV-Datei:

"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"

Beim Parsen der CSV-Datei erhalte ich jedoch folgende Fehlermeldung:

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>'

Dann habe ich versucht, die Daten zu vereinfachen, d.h.

"name","age","email"
"jignesh","30","[email protected]"

trotzdem bekomme ich den gleichen fehler:

      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>'

Wieder habe ich versucht, die Daten wie folgt zu vereinfachen:

name,age,email
jignesh,30,[email protected]

und es funktioniert. Siehe die Ausgabe unten:

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

Aber ich werde die CSV-Dateien mit zitierten Daten erhalten, daher suche ich nicht nach einer Lösung zum Entfernen von Zitaten. Ich kann nicht herausfinden, was den Fehler verursacht: CSV :: MalformedCSVError: Illegales Zitieren in Zeile 1. in meinen früheren Beispielen.

Ich habe überprüft, dass in der CSV keine führenden/nachfolgenden Leerzeichen vorhanden sind, indem ich in meinem Texteditor "Whitespace-Zeichen anzeigen" und "Zeilenenden anzeigen" aktiviert habe. Außerdem habe ich die Codierung wie folgt überprüft.

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

Hinweis: Ich habe versucht, auch CSV.read zu verwenden, aber derselbe Fehler bei dieser Methode.

Kann mir bitte jemand helfen, das Problem zu lösen und mir klar zu machen, wo es schief geht?

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

Ich habe gerade folgenden Beitrag gefunden: http://www.Ruby-forum.com/topic/448070 und Folgendes versucht:

  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

und bekam folgende Ausgabe:

   =======["\xEF\xBB\xBF'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'"]

das fehlerhafte Lesen der Daten als Standard col_sep ist ein Komma. Ich habe jedoch versucht, quote_char zu verwenden:

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

aber es endete der folgende Fehler:

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

Danke, Jignesh

20
Jignesh Gohel
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

es ist nicht perfekt, aber es funktioniert meistens.

N.B. CSV.parse verwendet dieselben Parameter wie CSV.read, sodass entweder eine Datei oder Daten aus dem Speicher verwendet werden können

21
Vadym Tyemirov

Anand, danke für den Kodierungsvorschlag. Dies löste das Problem des illegalen Zitierens für mich.

Hinweis: Wenn Sie möchten, dass der Iterator die Kopfzeile überspringt, fügen Sie wie folgt headers: :first_row hinzu:

CSV.foreach("test.csv", encoding: "bom|utf-8", headers: :first_row)
13
theUtherSide

Ich hatte gerade ein Problem wie dieses und entdeckte, dass CSV keine Leerzeichen zwischen dem Colsep und dem Anführungszeichen mag. Nachdem ich die entfernt hatte, ging alles gut ... So hatte ich:

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

aber einmal habe ich die Lücken mit rausgehauen

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

ergebend

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

alles lief gut.

12
user2391694

Ich hatte ein Problem mit dem Markenzeichen, das diesen Fehler ausgelöst hat.

Das Markenzeichen wird in UTF-8 in "!" Übersetzt, daher war es das offene Anführungszeichen, das den Fehler ausgelöst hat. Also habe ich Folgendes getan:

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

Und dann habe ich versucht, mein CSV-Objekt zu erstellen, und es hat gut funktioniert.

1
Elena Tanasoiu

Ich habe versucht, die Datei zu lesen und eine Zeichenfolge zu erhalten und diese in eine CSV-Tabelle zu analysieren, erhielt jedoch eine Ausnahme:

CSV.read(File.read('file.csv'), headers: true)
CSV::MalformedCSVError: Unclosed quoted field on line 1794.

Keine der hier gegebenen Antworten hat für mich funktioniert. Tatsächlich hat der mit den höchsten Stimmen so lange analysiert, dass ich schließlich die Hinrichtung beendete. Es hat höchstwahrscheinlich viele Ausnahmen ergeben, und diese Zeit kostet eine große Datei.

Noch problematischer ist der Fehler nicht, da es sich um eine große CSV-Datei handelt. Wo genau steht Linie 1794? Ich habe die Datei in LibreOffice geöffnet, die problemlos geöffnet wurde. Zeile 1794 war die letzte Datenzeile der CSV-Datei. Das Problem hatte also offenbar mit dem Ende der CSV-Datei zu tun. Ich beschloss, den Inhalt als Datei mit File.read zu überprüfen. Ich habe festgestellt, dass die Zeichenfolge mit einem Wagenrücklaufzeichen endete:

,\"\"\r

Ich entschied mich für chomp und entfernte den Wagenrücklauf am Ende der Datei. Hinweis: Wenn $/gegenüber dem standardmäßigen Ruby-Datensatztrennzeichen nicht geändert wurde, entfernt chomp auch Wagenrücklaufzeichen (dh\n,\r und\r\n).

CSV.parse(File.read('file.csv' ).chomp, headers: true)
 => #<CSV::Table mode:col_or_row row_count:1794>

Und es hat funktioniert. Das Problem war das\r Zeichen am Ende der Datei.

0
Donato