CSV. Você acaba de se fuder

Cuidado a postagem abaixo contem ódio, muito ódio.

Eu trabalho com frequência com arquivos no formato CSV (Comma-Separated Values) para manipulação de dados. Se você é pesquisador ou um programador você já trabalhou e teve alguma dor de cabeça com a manipulação de arquivos no formato CSV. Vamos começar com a definição formal do CSV.

O documento que define o formato do CSV é o RFC 4180. Precisa ter alguma noção de informática para entender o documento na integra, mas vamos comentar os pontos importantes.

Definições

Each record is located on a separate line, delimited by a line break (CRLF). For example:

aaa,bbb,ccc CRLF

zzz,yyy,xxx CRLF

 

Então temos o exemplo com dois registros e cada registro é separado por uma quebra de linha. Para os menos versados em informática o CRLF são dois caracteres invisíveis que compõem a quebra de uma linha. Para quem já passo pelo inferno de formatar algum documento seguindo normas ABNT ou de pós-graduações deve conhecer o símbolo ¶. Ele mostra caracteres invisíveis como o espaço e a quebra de linha.

 

The last record in the file may or may not have an ending line break. For example:

aaa,bbb,ccc CRLF

zzz,yyy,xxx

 

Não mudou muito do exemplo anterior, mas agora sabemos que o último registro não precisa ter uma quebra de linha. Isso significa que se você abrir um CSV no bloco de notas a última linha pode ser vazia ou não, somente isso!

 

There maybe an optional header line appearing as the first line of the file with the same format as normal record lines. This header will contain names corresponding to the fields in the file and should contain the same number of fields as the records in the rest of the file (the presence or absence of the header line should be indicated via the optional “header” parameter of this MIME type). For example:

field_name,field_name,field_name CRLF

aaa,bbb,ccc CRLF

zzz,yyy,xxx CRLF

 

Vamos ignorar a parte do MIME type que não é o foco no momento e tentar diferenciar apenas o exemplo atual dos anteriores. Podemos ter um novo registro que é definido como cabeçalho do arquivo que deve aparecer na primeira linha. Trocando em miúdos podemos ter uma linha no começo do arquivo que contém o título das colunas.

 

Within the header and each record, there may be one or more fields, separated by commas. Each line should contain the same number of fields throughout the file. Spaces are considered part of a field and should not be ignored. The last field in the record must not be followed by a comma. For example:

aaa,bbb,ccc

 

Aqui temos a definição de campos, do separador (vírgula) e três regras: devemos ter o mesmo número de campos em todo o arquivo, espaços não devem ser ignorados e o último campo não deve ter o separador. No exemplo acima temos o CSV com um registro e três campos no total, repare que com todas as definições que temos até agora já começa a lembrar o CSV que manipulamos no dia a dia.

 

Each field may or may not be enclosed in double quotes (however some programs, such as Microsoft Excel, do not use double quotes at all). If fields are not enclosed with double quotes, then double quotes may not appear inside the fields. For example:

“aaa”,”bbb”,”ccc” CRLF

zzz,yyy,xxx

 

Não tem muito o que dizer dessa definição, podemos limitar os campos dentro de aspas duplas e caso não seja delimitado por aspas duplas pode ocorrer dentro do campo. Você vai entender melhor na próxima.

 

Fields containing line breaks (CRLF), double quotes, and commas should be enclosed in double-quotes. For example:

“aaa”,”b CRLF

bb”,”ccc” CRLF

zzz,yyy,xxx

 

É aqui onde a merda toda geralmente acontece. Até aqui foi dito que a vírgula é o separador de campos, mas você por algum motivo quer colocar parágrafos nos campos. É bem provável que você vai ter várias vírgulas no seu CSV. Isso vai CAGAR a interpretação do CSV como foi definida até agora. Para resolver esse problema existe a opção de usar as aspas duplas. Exemplo:

“1,2,3”,”aaa”

Temos um registro com dois campos. Sem as aspas teremos o caso:

1,2,3,aaaa

Temos um registro com 4 campos. Se você no seu Excel quer ver 1,2,3 na mesma célula e fica aparecendo cada número em uma coluna e “empurrando” os outros campos para a direita o motivo foi uma implementação errada do CSV. Da mesma forma se quiser colocar várias linhas dentro de um campo é só seguir o próprio exemplo da penúltima definição.

 

If double-quotes are used to enclose fields, then a double-quote appearing inside a field must be escaped by preceding it with another double quote. For example:

“aaa”,”b””bb”,”ccc”

 

Você deveria estar se perguntando como colocar aspas duplas nos campos já que ela tem um significado definido no CSV. Essa definição existe para resolver esse problema. É só colocar duas “” para aparecer uma “.

Beleza, acabamos de ver a definição. Parece legal bem redonda né?

CSV, na vida real

Tudo bem que o RFC só surgiu depois (2005) do uso do CSV ser bem difundido, mas não é possível que ninguém ainda conhece o RFC.

Lembro que estava com problema de abrir um CSV de 4gb para realizar um processamento a nível de coluna e um amigo da TI teve a ideia genial de fazer um programinha em Java para interpretar o CSV e aplicar meu filtro. Fiquei bem feliz, iam fazer meu trabalho pela primeira vez. Meu colega implementou simplesmente dividindo os campos pelo separador (tabulação). Obviamente deu merda e eu tive que usar uma biblioteca para aplicar o filtro.

Outro caso que eu não esqueço era a diferença que o mesmo arquivo CSV tinha dentro da mesma organização (GBIF). Os dados do GBIF são coletados pelo seu próprio software IPT e a comunidade internacional consegue ter acesso no próprio portal online do GBIF. Eu trabalhei com esses dados com frequência e ficava maravilhado de como um CSV produto do portal GBIF não conseguia ser interpretado corretamente novamente pelo software IPT (sua fonte original). O principal problema era o separador tabulação, a justificava era que a vírgula era muito comum e poderia “estragar” o CSV. Estragar como caralho!? O padrão define tratamento do separador padrão (vírgula) usando aspas duplas. Eles também geravam CSVs nesse formato:

“aaa”,”bb”b,ccc

“aaa”,”bb”b”,ccc

 

Que merda é essa?! Como que interpreta o segundo campo no primeiro registro? Ele é “bb”b? Ou é bbb? Não dá para saber e cada software (IPT, GBIF, LibreOffice, Excel) vai interpretar de um jeito o que gera o inferno na manipulação de dados. Parece bobeira quando você pensa no seu CSV de 20 linhas da graduação, mas quando você entra na escala de milhões de linhas os dados são automaticamente classificados como de “baixa qualidade” ou “lixo”. As coisas estão mudando aos poucos, no https://github.com/gbif/gbif-common/issues/1 eu reporto para o GBIF que a biblioteca deles não segue o RFC.

Grande parte da culpa é do Excel. Se você usa as configurações regionais do Windows em Português Brasileiro o seu CSV vai utilizar o separador “;”. A Microsoft não deve ter recursos suficientes para ler a desgraça do RFC. O CSV não precisa de outro separador para resolver o problema. O uso de aspas duplas resolve o problema!

Se você é um programador não implemente padrões sem ler. Não, faça melhor. Siga a regra de implementação de criptografia. Use uma boa biblioteca que implementa o que você precisa.

Se você utiliza CSV com frequência você vai se FUDER, eventualmente.

Anúncios

Uma opinião sobre “CSV. Você acaba de se fuder

  1. De fato, boa parte da culpa muitas vezes é da Microsoft. O LibreOffice te permite escolher o separador (vírgula, ponto-e-vírgula, tab) e a codificação (que pro Bill Gates parece que até hoje não existe). Eu prefiro tab, pq sim, vírgulas são muito comuns, e usar aspas em tudo aumenta o tamanho do arquivo desnecessariamente. E sobre codificação, bendito dia em que conheci o UTF-8, que nos livra pra sempre do problema de ã, ç, é, ô… virarem quadradinhos, como permite até mesmo a utilização de caracteres chineses, russos, árabes… Existem sites específicos contando os inúmeros males introduzidos pela Microsoft, pena que a maioria tenha preguiça de se livrar do Windows e reforçar o mundo Linux. A própria indústria dificulta essa transição, lançando drivers (de vídeo, por exemplo, né NVIDIA?) de código fechado, não atualizando recursos como Flash, por exemplo, entre outros.

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair /  Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

Conectando a %s

%d blogueiros gostam disto: