Eine kurze Geschichte über FEFF, ein unsichtbares UTF-8-Zeichen, das unsere CSV-Dateien zerstört hat

Heute ist beim Versuch, einige Datenbank-Seeds aus einer CSV zu erstellen, ein Fehler aufgetreten. Diese CSV wurde ursprünglich von mir mithilfe eines Ruby-Skripts erstellt, das die Ausgabe in eine Datei leitete und als CSV speicherte.

Die CSV wurde in Git eingecheckt und wurde eine Weile verwendet, bis wir einige Teile davon aktualisieren mussten, indem wir eine neue Spalte hinzufügten und einige Werte korrigierten.

Obwohl wir den genauen Grund noch nicht kennen, ist meine Theorie, dass Excel für Mac (wir verwenden alle Macs) einige zusätzliche Metadaten hinzugefügt hat, selbst nachdem die Datei als CSV gespeichert wurde.

Dies wiederum führte dazu, dass jeder, der den Startwert verwendet, den folgenden Fehler erhielt:

CSV::MalformedCSVError: Illegal quoting in line 1.

Ich habe die CSV-Datei geöffnet und nichts sah verdächtig aus. Mein erster Gedanke war, dass einige linke / rechte Anführungszeichen irgendwie in die Datei eingemischt wurden, anstatt nur die 'normalen' doppelten Anführungszeichen : ". Bei weiteren Untersuchungen gab es jedoch nichts Außergewöhnliches. Dies führte dazu, dass ich einfach die gesamte Datei löschte und die erste Zeile erneut ausgab.

Ich habe diese Datei erneut gespeichert und die Migration ausgeführt:

CSV::MalformedCSVError: Illegal quoting in line 1.

Was?!

Okay, das hat mich verrückt gemacht. Ich öffnete eine neue Datei, tippte die exakte einzelne Zeile erneut ein und führte die Migration aus. Es funktionierte. Also, was war in dieser Datei?!

Nur ein Weg, um herauszufinden:

cat companies.csv | pbcopy | pbpaste > temp.csv rm companies.csv mv temp.csv companies.csv git diff

OSX hat also diese beiden Funktionen, die sehr nützlich sind: pbcopyund pbpaste. Im Grunde alles , was zum Ausleiten pbcopywird in der Zwischenablage und pbpastePuts , was Sie auf Ihrem Zwischenablage Standardausgabe haben (stdout). Es werden jedoch alle Formatierungen entfernt.

Sehr nützlich, wenn Sie nur Text von irgendwoher kopieren und ihn ohne Formatierung in einen WYSIWYG-Editor einfügen möchten. Zum Beispiel beim Schreiben einer E-Mail aus Google Mail.

Ich habe dann die Originaldatei entfernt und die neue 'unformatierte' Datei mit demselben Dateinamen gespeichert, damit ich den Unterschied erkennen konnte.

Und wir haben endlich den unsichtbaren Mann gesehen:

Eine schnelle Google-Suche U+FEFFergab , dass unser Freund a genannt wurde ZERO WIDTH NO-BREAK SPACE. Eine kurze Reise zu Wikipedia erzählte uns auch von den tatsächlichen Verwendungszwecken für U+FEFF, besser bekannt als Byte order markoder BOM.

Unser Freund FEFFmeint verschiedene Dinge, aber es ist im Grunde ein Signal für ein Programm, wie man den Text liest. Es kann UTF-8(häufiger) UTF-16oder sogar sein UTF-32.

FEFFselbst ist für UTF-16- in UTF-8ist es allgemein bekannt als 0xEF,0xBB, or 0xBF.

Nach meinem Verständnis hat Excel beim Öffnen und Speichern der CSV-Datei in Excel einen Platz für unseren unsichtbaren blinden Passagier geschaffen U+FEFF. Und vor der Datei zu booten!

Excel hat etwas Magie gemacht, und es wurde wahrscheinlich in UTF-16statt gespeichert UTF-8. UTF-8versteht es nicht BOMund behandelt es nur als Nicht-Zeichen, so dass die Datei in Ordnung war. Aber Ruby CSVdachte, dass etwas nicht stimmte, weil er davon ausging, dass es sich um die gelesene Datei handelte UTF-8und Mr. nicht ignorieren konnte U+FEFF.

Lektion gelernt: Öffnen (und speichern!) Sie keine CSV-Datei in Excel, wenn Sie sie an Rubys CSVParser weiterleiten möchten .

Wenn Sie jemals auf einen solchen Fehler stoßen, suchen Sie nach versteckten Zeichen, die von Ihrem Editor nicht angezeigt werden. Wenn Sie noch nicht sehen können und OSX verwenden, dann pbcopyund pbpasteSie werden helfen - sie alle Formatierungen oder versteckten Zeichen aus dem Text zusätzlich Streifen aus auf das Kopieren und Einfügen.