Kiire lugu FEFFist, nähtamatust UTF-8 tähemärgist, mis hävitas meie CSV-failid

Täna ilmnes CSV-st andmebaasi seemnete loomisel viga. Selle CSV lõin algselt minu poolt, kasutades Ruby skripti, mis viis väljundi faili ja salvestati CSV-na.

CSV registreeriti Gitis ja seda oli mõnda aega kasutatud, kuni pidime selle mõnda osa värskendama, lisades uue veeru ja parandades mõned väärtused.

Ehkki me ei tea veel täpset põhjust, on minu teooria selline, et kuidagi lisas Excel for Mac (me kõik kasutame Mac-e) isegi pärast faili CSV-na salvestamist sellele mõned täiendavad metaandmed.

See pani omakorda kõik seemet kasutajad saama järgmise tõrke:

CSV::MalformedCSVError: Illegal quoting in line 1.

Avasin CSV-faili ja miski ei tundunud kahtlane. Minu esimene mõte oli mõned vasakule / paremale jutumärkides olid kuidagi segada faili asemel lihtsalt "normaalne" jutumärgid: ". Kuid edasisel uurimisel polnud midagi erakordset. See viis mind lihtsalt kogu faili tühjendama ja tegelikult kirjutasin esimese rea uuesti välja.

Salvestasin selle faili uuesti ja käitsin migreerimise:

CSV::MalformedCSVError: Illegal quoting in line 1.

Mida?!

Okei, see ajas mind pähe. Avasin uue faili, tippisin uuesti täpse ühe rea ja jooksin migratsiooni. See toimis. Mis siis selles toimikus oli ?!

Ainult üks viis teada saada:

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

Nii et OSX-il on need kaks funktsiooni, mis on väga kasulikud: pbcopyja pbpaste. Põhimõtteliselt pbcopyjõuab kõik lõikepuhvrisse lülitatuna lõikepuhvrisse ja pbpasteasetab selle, mis teil on, tavalisele väljundile (stdout). Kuid see eemaldab kogu vormingu.

Väga kasulik, kui soovite teksti lihtsalt kuskilt kopeerida ja soovite kleepida WYSIWYG-i redaktorisse ilma kogu vorminduseta. Nagu näiteks Gmailist meilisõnumite kirjutamisel.

Seejärel eemaldasin algse faili ja salvestasin uue „vormindamata” faili sama failinimega, et näeksin erinevust.

Ja lõpuks nägime nähtamatut meest:

Kiire Google'i otsing U+FEFFnäitas meile, et meie sõpra kutsuti a ZERO WIDTH NO-BREAK SPACE. Kiire reis Wikipediasse rääkis ka tegelikest kasutusaladest U+FEFF, mida tuntakse sagedamini kui Byte order markvõi BOM.

Meie sõber FEFFtähendab erinevaid asju, kuid see on põhimõtteliselt signaal programmi jaoks, kuidas teksti lugeda. See võib olla UTF-8(sagedamini) UTF-16või isegi UTF-32.

FEFFise on selle jaoks UTF-16- UTF-8seda tuntakse rohkem kui 0xEF,0xBB, or 0xBF.

Minu arusaamade järgi lõi Excel CSV-faili avamisel ja salvestamisel Excel ruumi meie nähtamatule mahajätjale U+FEFF. Ja faili ees käivitamiseks!

Excel tegi mingit maagiat ja tõenäoliselt salvestati see UTF-16asemel UTF-8. UTF-8ei saa aru BOMja kohtleb seda lihtsalt mittemärgina nii visuaalselt, fail oli korras. Kuid Ruby CSVarvas, et midagi on valesti, kuna ta eeldas, et fail, mida ta loeb, on UTF-8ja ta ei saa hr U+FEFF.

Nii et õppetund: ärge avage (ja salvestage!) CSV-faili Excelis, kui soovite selle Ruby CSVparserisse edastada .

Kui teil on kunagi sellist viga, otsige kindlasti peidetud märke, mida teie redaktor ei näita. Kui te ikka ei näe seda ja kasutate OSX-i, siis pbcopyja pbpasteaitab teid välja - need eemaldavad teksti kopeerimise ja kleepimise kõrval kõik vormindused või peidetud märgid.