Кратка прича о ФЕФФ-у, невидљивом УТФ-8 лику који је уништио наше ЦСВ датотеке

Данас смо наишли на грешку приликом покушаја креирања неких семена базе података из ЦСВ-а. Овај ЦСВ сам првобитно генерисао користећи Руби скрипту која је цевоводом послала излаз у датотеку и сачувала као ЦСВ.

ЦСВ је пријављен у Гит и користио се неко време док нисмо морали да ажурирамо неке његове делове додавањем нове колоне и поправљањем неких вредности.

Иако још не знамо тачан разлог, моја теорија гласи да је Екцел за Мац (сви користимо Мац) додао неке додатне метаподатке чак и након што је датотеку сачувао као ЦСВ.

Због тога је свако ко користи семе примио следећу грешку:

CSV::MalformedCSVError: Illegal quoting in line 1.

Отворио сам ЦСВ датотеку и ништа није изгледало сумњиво. Моја прва мисао је била нека лево / десно наводници су на неки начин мешају у датотеку уместо само на 'нормалним' двоструким наводницима: ". Али у даљој истрази није било ништа необично. То ме је навело да само избришем целу датотеку и заправо поново откуцам први ред.

Поново сам сачувао ту датотеку и покренуо миграцију:

CSV::MalformedCSVError: Illegal quoting in line 1.

Шта?!

Ок, ово ме излуђивало. Отворио сам нову датотеку, поново откуцао тачно један ред и покренуо миграцију. Успело је. Па шта је било у том досијеу ?!

Само један начин да сазнате:

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

Дакле, ОСКС има ове две врло корисне функције: pbcopyи pbpaste. Углавном све што pbcopyсе унесе у ваш цлипбоард и pbpasteстави оно што имате у цлипбоард на стандардни излаз (стдоут). Али уклања све форматирање.

Веома корисно када желите да копирате неки текст однекуд и желите да га налепите у ВИСИВИГ едитор без свих форматирања. На пример, када пишете е-пошту са Гмаил-а.

Затим сам уклонио оригиналну датотеку и сачувао нову „неформатирану“ датотеку са истим именом, како бих могао да видим разлику.

И коначно смо видели невидљивог човека:

Брза Гоогле претрага нам је рекла да се наш пријатељ U+FEFFзвао а ZERO WIDTH NO-BREAK SPACE. Такође, кратко путовање на Википедију нам је рекло о стварној употреби за U+FEFF, познатију као Byte order markили BOM.

Наш пријатељ FEFFзначи различите ствари, али у основи је то сигнал програму како читати текст. Може бити UTF-8(чешће) UTF-16, или чак UTF-32.

FEFFсам је за UTF-16- у UTF-8њему је познатији као 0xEF,0xBB, or 0xBF.

Из мог разумевања, када је отворена ЦСВ датотеку у Екцел и спасио Екцел створио простор за наше невидљиве слепи путници, U+FEFF. И испред датотеке за покретање!

Екцел је учинио магију и вероватно је сачуван UTF-16уместо UTF-8. UTF-8не разуме BOMи само га третира као не-карактер, па је визуелно датотека била у реду. Али Руби је CSVпомисао да нешто није у реду, јер претпоставља фајл је читање било UTF-8и да није могао да игнорише Мр. U+FEFF.

Дакле, научена лекција: немојте отварати (и чувати!) ЦСВ датотеку у програму Екцел ако је желите да унесете у Руби-јев CSVпарсер.

Ако икада наиђете на такву грешку, потражите скривене знакове које ваш уредник не приказује. Ако и даље не можете да га видите и користите ОСКС, тада ће вам pbcopyи pbpasteпомоћи - уклањају из текста свако обликовање или скривене знакове, поред копирања и лепљења.