Dlaczego przecinek jest złym separatorem / separatorem rekordów w plikach CSV?

32

Czytałem to artykuł i jestem ciekawy właściwej odpowiedzi na to pytanie.

Jedyne, co przychodzi mi do głowy, to być może, że w niektórych krajach separatorem dziesiętnym jest przecinek i mogą być problemy z udostępnianiem danych w CSV , ale tak naprawdę nie jestem pewien mojej odpowiedzi.

David Gasquez
źródło
6
Prawie każdy separator jest lepszy niż przecinek. Powodem jest to, że gdy pliki rozdzielane przecinkami są odczytywane w niektórych narzędziach do analizowania danych, przecinki mogą być mylone z interpunkcją, zaburzając „układ” pól lub kolumn.
Mike Hunter,
33
Cynik, zauważając, że ten artykuł jest fragmentem SAS, może sugerować, że być może SAS ma problemy z przetwarzaniem plików CSV przecinkami :-).
whuber
3
@whuber - SAS (z mojego doświadczenia) może zmagać się z plikami CSV, bez względu na to, czy mają przecinki, czy nie, wymagając ogromnego ręcznego kodowania każdej dziwnej rzeczy, której SAS nie lubi.
Jeremy Miles,
8
Poszukiwania coraz bardziej niejasnych ograniczników - rur, pilcrows, cierni - są desperacją, co sugeruje, że uzgodnienie i przestrzeganie standardu jest naprawdę jedynym bezpiecznym sposobem wymiany danych w plikach tekstowych z ogranicznikami. A uniwersalny standard musi pozwalać na reprezentację dowolnego ciągu tekstowego (podobnie jak RFC4180), zamiast opierać się na założeniu, że niektóre nie będą musiały być i mogą być użyte do innej pracy.
Scortchi - Przywróć Monikę
2
(a) Często pomyślnie importowałem pliki .csv. (b) Radzę ludziom, aby nie używali .csv, jeśli mają przecinki w swoich danych. Nie są ze sobą sprzeczne. To niefortunne, że (b) wymaga wyjaśnienia w niektórych kwartałach.
Nick Cox,

Odpowiedzi:

33

Specyfikacja formatu CSV jest zdefiniowana w RFC 4180 . Ta specyfikacja została opublikowana, ponieważ

nie istnieje formalna specyfikacja, która pozwala na szeroki zakres interpretacji plików CSV

Niestety od 2005 roku (data publikacji RFC) nic się nie zmieniło. Wciąż mamy szeroką gamę wdrożeń. Ogólne podejście zdefiniowane w RFC 4180 polega na umieszczaniu pól zawierających znaki takie jak przecinki w cudzysłowie, jednak to zalecenie nie zawsze spełnia inne oprogramowanie.

Problem polega na tym, że w różnych europejskich lokalizacjach przecinek służy jako kropka dziesiętna, więc 0,005zamiast tego piszesz 0.005. Jednak w innych przypadkach przecinki są używane zamiast spacji do sygnalizowania grup cyfr, np. 4,000,000.00(Patrz tutaj ). W obu przypadkach użycie przecinków może prowadzić do błędów w odczycie danych z plików csv, ponieważ twoje oprogramowanie tak naprawdę nie wie, czy 0,005, 0,1są to dwie liczby, czy cztery różne liczby (patrz przykład tutaj ).

Wreszcie, jeśli przechowujesz tekst w pliku danych, przecinki są znacznie bardziej powszechne w tekście niż, na przykład, średniki, więc jeśli tekst nie jest ujęty w cudzysłów, dane takie można również łatwo odczytać z błędami .

Nic nie czyni przecinków lepszymi ani gorszymi separatorami pól, o ile pliki CSV są używane zgodnie z zaleceniami RFC 4180, które chronią przed problemami opisanymi powyżej. Jeśli jednak istnieje ryzyko zastosowania uproszczonego formatu CSV, który nie zawiera pól w cudzysłowie, lub zalecenie może być zastosowane niespójnie, wówczas inne separatory (np. Średnik) wydają się bezpieczniejsze.

Tim
źródło
6
Cóż, każde oprogramowanie implementujące rzeczywisty standard CSV zdefiniowany w RFC 4180 z pewnością wiedziałby dokładnie, jak interpretować dowolny ciąg. Argument, że stosowanie ,zamiast rzadszego separatora powoduje rozdęcie danych, ponieważ trzeba przez cały czas ich unikać, jest jednak prawdziwy. I oczywiście są wszyscy ludzie, którzy myślą, że wiedzą, jak działa CSV, ale tak naprawdę nie.
Voo,
2
@Voo Tak, ale ponieważ pliki „csv” są używane w tak chaotyczny sposób, bezpieczniej jest nie używać przecinków, a zamiast nich używać innych separatorów, np. Średników. To jest odpowiedź na pytanie OP. Nie ma nic „lepszego” w średnikach (lub innych przecinkach) w porównaniu do przecinków, w wielu przypadkach są one po prostu bezpieczniejszym wyborem.
Tim
2
@Voo +1 do Twojego komentarza. Jednak każdy, kto korzysta z CSV, tak naprawdę nie dba o rozdęte pliki danych!
whuber
17

Technicznie przecinek jest tak dobry, jak każdy inny znak, który może być użyty jako separator. Nazwa formatu bezpośrednio wskazuje, że wartości są rozdzielane przecinkami (wartości rozdzielane przecinkami).

Opis formatu CSV wykorzystuje przecinek jako separator.

Każde pole zawierające przecinek powinno być cytowane podwójnie. Nie powoduje to problemów z wczytywaniem danych. Patrz punkt 6 z opisu :

  1. Pola zawierające podział wiersza (CRLF), podwójne cudzysłowy i przecinki powinny być ujęte w cudzysłowy.

Na przykład funkcje read.csvi write.csvdomyślnie R używają przecinka jako separatora.

djhurio
źródło
4
To najlepsza odpowiedź, ponieważ odnosi się do valuestego, że są oddzielone przecinkami. Inni, nawiązując do europejskich formattingliczb, nie jest to problemem dla csv standard, jak poprawnie cytujesz pkt 6 powyżej. Istnieją rozbieżności z „prawidłowym użytkowaniem” w dowolnym formacie danych. Chodzi o to - poznaj swoje dane. Inni wspominają tablub ;ograniczają, ale mogą mieć te same problemy, co przecinki, gdy masz do czynienia z danymi wprowadzonymi przez użytkownika (być może za pośrednictwem formularza i przechwyconego przez bazę danych - musiałem się sprzeczać z polami do swobodnego wprowadzania tekstu, które ludzie mam tłuszcz w palcach tab... to jest do bani)
Adrian Torrie
Odpowiedź Tima została teraz zredagowana, aby zawierała informacje dostarczone przez @djhurio.
Adrian Torrie,
11

Oprócz tego, że jest cyfrowym separatorem cyfr, stanowi także część adresu (np. Adres klienta itp.) W wielu krajach. Podczas gdy niektóre kraje mają krótkie, dobrze zdefiniowane adresy, wiele innych ma długie adresy, w tym czasami dwa przecinki w tej samej linii. Dobre pliki CSV zawierają wszystkie takie dane w podwójnych cudzysłowach. Jednak nadmiernie uproszczone, źle napisane parsery nie przewidują ich czytania i różnicowania. (Następnie pojawia się problem używania podwójnych cudzysłowów jako części danych, takich jak cytat z wiersza).

Wirowy Umysł
źródło
2
(+1) Standard przewiduje stosowanie podwójnych cytatów jako części danych, nalegając na ich podwojenie: „Belloc”, „Tarantella”, „” „pchły dokuczające w Wysokich Pirenejach” „”. W Anglii często zdarza się, że pola adresowe zawierają nazwę domu w cudzysłowie, a więc: „Chatsworth”, Melton Road, Leamington. (Nie jest jasne, dlaczego: Fowler narzekał, że „wydaje się, że implikacja: życie w domu, który rozsądni ludzie nazywają„ 164 Melton Road ”, ale jeden głupiec lubi nazywać„ Chatsworth ””.)
Scortchi - Przywróć Monikę
1
@Scortchi Wygląda na to, że nauczyliśmy się tych samych wierszy w wieku 12 lat (błąd +/-). Obawiam się, że to, co przeczytałem jako niefortunny angielski snobizm wyższej klasy średniej z początku XX wieku dla nawyków niższej klasy średniej, przesłania twój ostatni przykład, który nie będzie przejrzysty poza małą grupą.
Nick Cox,
@NickCox: Dwanaście brzmi dobrze. Zabawne, że nie pamiętam, czy przeczytałem w tym roku jakieś wiersze, nie wspominając już o ich wierszach. Chociaż punkt Fowlera dotyczył wpływu na czytelnika niepotrzebnych cudzysłowów (patrz unnecessaryquotes.com ), myślę, że masz rację, widząc wpływ snobizmu na wybrany przez siebie przykład. W każdym razie mam nadzieję, że raczej niewielka kwestia, na którą należy uważać, jeśli kiedykolwiek zostanie wysłany plik CSV zawierający adresy w języku angielskim, jest jasna dla wszystkich, pomimo moich rozbieżności.
Scortchi - Przywróć Monikę
1
w Indiach ludzie, którzy budują swoje pierwsze domy (nie mieszkania), zachowują innowacyjną kwiatową nazwę, często w języku ojczystym lub w sanskrycie, a są to podwójne cytaty, takie jak „Guru Kripa”. Nazwy takie jak Genelia D'Souza i Derek O'Brien są również popularne. Następnie adresy z napisem „Stare drzwi nr nnn / Nowe drzwi nr mm / c”, z powodu zmiany numeracji przez rząd, jeszcze bardziej komplikują przechowywanie adresów, ponieważ mają nieoczekiwane ukośniki i pojedyncze cudzysłowy.
Whirl Mind
@WhirlMind: To ciekawe - zauważyłem wiele - cóż, więcej niż się spodziewałem - szkockich gaelickich i walijskich nazw domów w Anglii, co jest być może najbliższym odpowiednikiem wyboru języka ojczystego, w którym można nazwać swój dom.
Scortchi - Przywróć Monikę
9

Chociaż odpowiedź @Tim jest poprawna - chciałbym dodać, że „csv” jako całość nie ma wspólnego standardu - zwłaszcza reguły dotyczące ucieczki nie są w ogóle zdefiniowane, co prowadzi do „formatów”, które można odczytać w jednym programie, ale nie w innym . Jest to uzasadnione tym, że każdy „programista” pod słońcem myśli po prostu „oooh csv- Zbuduję własny parser!” a następnie pomija wszystkie przypadki krawędzi.

Co więcej, csv całkowicie brakuje możliwości przechowywania metadanych, a nawet typu danych kolumny - co prowadzi do kilku dokumentów, które należy przeczytać, aby zrozumieć dane.

Christian Sauer
źródło
5
Tak, istnieją standardowe narzędzia.ietf.org/ html/rfc4180 i wiele innych formatów nie przechowuje żadnych metadanych, po prostu nie jest przeznaczone do przechowywania metadanych - pliki .txt również nie przechowują metadanych dotyczących dokumentów tekstowych ...
Tim
4
Tim, ten standard jest ignorowany częściej niż nie, co czyni go niestandardowym ,,,
Christian Sauer
8
Wspaniałą rzeczą w standardach jest to, że jest tak wiele do wyboru. (Różnie zmutowane i przypisane.)
Nick Cox
4

Jeśli możesz porzucić separator przecinka i użyć znaku tabulacji, odniesiesz znacznie większy sukces. Możesz zostawić plik o nazwie .CSV, a importowanie do większości programów zwykle nie stanowi problemu. Po prostu zaimportuj plik po prostu określ TAB rozdzielany, a nie przecinkami. Jeśli w twoich danych są przecinki, będziesz mieć problem z określeniem rozdzielania przecinków, jak dobrze wiesz.

Goryl
źródło
5
Jeśli w twoich danych są zakładki, obowiązuje odwrotność. Jest to, przynajmniej z mojego doświadczenia, mniej prawdopodobne.
Nick Cox,
@Nick and Gorilla: Miałem dobre wyniki |jako ogranicznik w plikach tekstowych rekordów w domowych plikach CSV podobnych do plików (z tytułami książek i innymi metadanymi dokumentów). |nigdy nie pojawia się w danych, z którymi pracuję, więc mogę po prostu pisać skrypty Perla, które po prostu dzielą / łączą się bez sprawdzania jakiegokolwiek cytowania. Dotyczyło to jednorazowego projektu, który polega tylko na przetwarzaniu metadanych zapisanych z bazy danych MS Access. W przypadku każdego większego projektu lub jeśli planujesz długoterminowe przechowywanie danych w tym formacie, wybierz coś bardziej niezawodnego! Zawsze mogłem coś ulepszyć, jeśli partia tego miesiąca coś zepsuła.
Peter Cordes,
@PeterCordes Wierzę ci i cokolwiek działa. Ale oczywiście kosztem separatorów idiosynkratycznych może być potrzeba wyjaśnienia tego innym i kluczowym jest, aby mogli bez problemu importować takie pliki danych. W obliczu nietypowego formatu pliku niezbędny jest dostęp do procedury, funkcji lub polecenia, które mogą dzielić łańcuchy na dowolne separatory.
Nick Cox,
@PeterCordes Kiedy napisałem splitpolecenie dla Staty, spojrzałem między innymi na odpowiednik Perla, aby zobaczyć, co zrobił, a czego nie zrobił. Nie kod źródłowy, tylko oferowana funkcjonalność.
Nick Cox,
1
@NickCox: Wiele funkcji perla jest całkiem dobrze zaprojektowanych, IMO. Wykonują pracę bez wielu specjalnych ograniczeń, takich jak w awk (co często jest dobre) lub esp. innych narzędzi Unix podoba cut, sorti uniq.
Peter Cordes,
4

ASCII zapewnia nam cztery znaki „separatora”, jak pokazano poniżej we fragmencie ze strony podręcznika ascii (7) * nix:

   Oct   Dec   Hex   Char
   ----------------------
   034   28    1C    FS  (file separator)
   035   29    1D    GS  (group separator)
   036   30    1E    RS  (record separator)
   037   31    1F    US  (unit separator)

Ta odpowiedź zapewnia porządny przegląd ich zamierzonego użycia.

Oczywiście, te kody kontrolne nie są przyjazne dla człowieka (czytelność i dane wejściowe) bardziej popularnych ograniczników, ale są akceptowalnym wyborem dla wewnętrznej i / lub efemerycznej wymiany danych między programami.

Ronald Straight
źródło
2
Ciekawy. Nie sądzę, żebym kiedykolwiek widział te używane na wolności ...
Matt Krause,
4

Problemem nie jest przecinek; problemem jest cytowanie. Bez względu na to, jakich ograniczników rekordów i pól używasz, musisz być przygotowany na spotkanie ich w treści. Potrzebujesz więc mechanizmu cytowania. A NASTĘPNIE potrzebujesz sposobu, aby pojawił się również cytat.

Przestrzeganie standardu RFC 4180 sprawia, że ​​wszystko jest prostsze dla wszystkich.

Osobiście musiałem napisać skrypt, aby prawdopodobnie naprawić dane wyjściowe z programu, który popełnił błąd, więc trochę się nad tym zastanawiam. „prawdopodobnie naprawić” oznacza, że ​​zadziałało dla MOICH danych, ale widzę sytuacje, w których się nie udałoby. (W obronie tego programu został napisany przed standardem).

Stig Hemmer
źródło