mygems

Como consertar um arquivo CSV quebrado ou malformado

Tudo em uma coluna, aspas soltas, linhas partidas, acentos quebrados. Veja como diagnosticar o que há de errado com um CSV e repará-lo.

Por uos ·

A maioria dos CSVs "corrompidos" não está corrompida. Um CSV é um arquivo de texto, e arquivos de texto raramente se estragam. O que quase sempre aconteceu é que o arquivo foi escrito com um conjunto de suposições e está sendo lido com outro: um delimitador diferente, uma codificação diferente, uma regra de aspas que o exportador aplicou errado.

Então o trabalho é diagnosticar antes de reparar. O sintoma mostra qual das seis causas é, e cada uma tem uma correção específica.

A resposta rápida

Olhe primeiro os bytes brutos, não o arquivo em uma planilha, que é uma ferramenta que esconde as evidências:

head -5 broken.csv          # the actual separators and quotes
file -I broken.csv          # the real encoding
wc -l broken.csv            # how many lines it thinks there are

Depois relacione o sintoma com a causa:

SintomaCausaCorreção
Tudo em uma única colunaDelimitador erradoReabrir informando o delimitador
é, ’, üUTF-8 lido como Latin-1Reabrir como UTF-8
 colado no primeiro cabeçalhoMarca de ordem de bytesRemover o BOM
Linhas quebradas no meio do registroQuebra de linha dentro de um campoCorrigir as aspas
A contagem de colunas muda depois da linha NUma aspa sem escapeEncontrar e reparar a linha N
O arquivo termina no meio de uma linhaGravação truncadaExportar de novo

1. Tudo cai em uma única coluna

De longe o caso mais comum, e nunca é culpa do arquivo.

Boa parte da Europa continental usa ponto e vírgula, porque lá a vírgula é o separador decimal. Muitas exportações com extensão .csv são, na verdade, separadas por tabulação. head -5 mostra qual é em um segundo.

A correção é dizer ao leitor qual é o separador, e não fazer localizar e substituir. Trocar ponto e vírgula por vírgula também troca os que estão dentro de valores entre aspas, e aí você tem um arquivo realmente quebrado.

  • Excel: não dê dois cliques. Dados → De Texto/CSV e escolha o delimitador na pré-visualização.
  • Google Planilhas: Arquivo → Importar → separador Personalizado.
  • Linha de comando: duckdb -c "SELECT * FROM read_csv('broken.csv', delim=';')"
  • No celular: um app que permita reabrir o arquivo com configurações de leitura explícitas, e não um que adivinha uma vez e desiste.
CSV Editor - Smart CSViPhone e iPad

Detecta automaticamente delimitadores, cabeçalhos e codificações e, o que importa aqui, permite reabrir o arquivo com configurações de leitura personalizadas quando o palpite está errado.

O que ele faz

2. Mojibake: é onde deveria haver é

O clássico problema de codificação. O arquivo é UTF-8 e algo o leu como Latin-1 ou Windows-1252. Os bytes estão intactos; a interpretação não.

file -I broken.csv
# broken.csv: text/plain; charset=utf-8

A correção: reabrir declarando UTF-8. No Excel, a caixa de diálogo de importação tem uma lista Origem do arquivo. Escolha 65001: Unicode (UTF-8). Na linha de comando:

iconv -f WINDOWS-1252 -t UTF-8 broken.csv > fixed.csv

Repare na direção. Se o arquivo for realmente Windows-1252 (sistemas antigos, algumas exportações de ERP), esse comando o converte. Se o arquivo já é UTF-8 e só está sendo exibido errado, converter piora tudo: você estaria codificando o mojibake. Confira com file -I antes de executar qualquer coisa.

3. order_id no nome da primeira coluna

Uma marca de ordem de bytes UTF-8: três bytes invisíveis no início do arquivo, gravados pelo Excel e por muitas ferramentas do Windows. Ela atrapalha a comparação de cabeçalhos em scripts e aparece como lixo em analisadores simples.

sed -i '' '1s/^\xEF\xBB\xBF//' broken.csv    # macOS
sed -i '1s/^\xEF\xBB\xBF//' broken.csv       # Linux

Só remova se algo adiante estiver engasgando com ela. O Excel, na verdade, quer o BOM. É assim que ele reconhece um CSV como UTF-8 quando você dá dois cliques, e removê-lo é o motivo de os acentos quebrarem para o colega a quem você enviou o arquivo.

4. Linhas partidas ao meio

Você esperava 10.000 linhas e recebeu 10.340, com fragmentos onde deveriam estar os endereços. Algum campo contém uma quebra de linha literal: um endereço, uma caixa de comentário, um parágrafo colado.

Isso é CSV válido se o campo estiver entre aspas:

id,name,notes
1,"Alice","Called back.
Wants a refund."

A RFC 4180 permite isso, e qualquer analisador decente lida com o caso. O problema acontece quando uma ferramenta divide por quebras de linha antes de pensar nas aspas, o que descreve a maioria dos one-liners de shell, vários importadores de planilha e muito código feito à mão.

A correção costuma estar no leitor, não no arquivo. Use um analisador que entenda aspas: DuckDB, o módulo csv do Python, o csvkit ou qualquer importação de planilha de verdade. Se o campo realmente não está entre aspas, a exportação está quebrada e exportar de novo é mais rápido que reparar.

Para confirmar qual é o seu caso:

csvclean -n broken.csv        # reports rows with the wrong field count

5. Tudo depois da linha 4.812 está errado

A contagem de colunas muda no meio do arquivo e nunca se recupera. É uma única aspa sem escape, e tudo depois dela está sendo lido dentro de uma string que nunca fecha.

id,product,price
1,"6"" pipe",4.50

Esse 6" deveria ter sido escrito 6"". Em vez disso, o analisador vê o valor terminar em 6, depois uma " solta abre outro, e o resto do arquivo fica dentro dele.

Como encontrar:

csvclean -n broken.csv
awk -F',' 'NF != 3 {print NR": "$0}' broken.csv   # rough, ignores quoting

O csvclean é o confiável; a linha com awk é uma aproximação rápida para arquivos sem vírgulas entre aspas. Com o número da linha em mãos, corrija essa linha manualmente: dobre a aspa interna ou troque por in. e siga em frente.

Fazer isso no celular é chato sem um app que pule para uma linha e edite uma única célula:

CSV File Viewer - Smart CSViPhone e iPad · Android

Abre o arquivo inteiro e permite pesquisar nele, para você achar a linha em que a estrutura quebra antes de decidir entre reparar ou exportar de novo.

O que ele faz

6. O arquivo simplesmente termina

A última linha é metade de um registro, ou o tamanho do arquivo é suspeitamente redondo. A gravação foi interrompida, ou o download.

tail -3 broken.csv

Não há nada para reparar aqui. Os dados nunca foram gravados. Apague a última linha incompleta e aceite a perda, ou exporte de novo. Se foi um download, compare o Content-Length com o tamanho real antes de culpar o arquivo.

As regras de reparo

Quatro hábitos que transformam a maioria dos problemas acima em não-eventos:

  1. Trabalhe em uma cópia. cp broken.csv broken.backup.csv. Toda correção desta página é um palpite até ser verificada, e um palpite que você não consegue desfazer é um mau negócio.
  2. Corrija o leitor antes do arquivo. A maioria dos sintomas aqui é configuração errada. Reescrever os dados para agradar um analisador mal configurado deixa você com dois problemas.
  3. Nunca use localizar e substituir em delimitadores. Isso atinge os que estão dentro de valores entre aspas e transforma um arquivo legível em um corrompido.
  4. Conte as linhas antes e depois. Em todo reparo. Se o número mudou e você não pretendia isso, o reparo quebrou alguma coisa.

Quando desistir e exportar de novo

Se mais do que um punhado de linhas estiver com a estrutura errada, pare de reparar. Uma exportação quebrada geralmente significa que o exportador tem um bug de aspas, e toda linha que ele produz é suspeita, inclusive as que parecem boas agora. Peça o arquivo de novo, e peça com aspas.

Perguntas

Por que meu CSV inteiro aparece em uma única coluna?
O arquivo usa um delimitador diferente do que o leitor presumiu. O ponto e vírgula é padrão em boa parte da Europa porque a vírgula é o separador decimal, e arquivos separados por tabulação levam a extensão .csv com uma frequência surpreendente. Rode head -5 no arquivo para ver o separador real e reabra informando esse delimitador, em vez de substituir caracteres.
Como corrijo caracteres estranhos como é em um CSV?
É um problema de codificação: o arquivo é UTF-8 e algo o leu como Latin-1 ou Windows-1252. Os bytes estão bons. Confira a codificação real com `file -I` e reabra declarando UTF-8; na caixa de importação do Excel, defina Origem do arquivo como 65001: Unicode (UTF-8). Só rode o iconv se o arquivo realmente for Windows-1252.
O que faz um CSV quebrar no meio do arquivo?
Quase sempre, uma única aspa sem escape. Um valor como 6" pipe precisa ser escrito com a aspa interna dobrada; sem isso, o analisador lê tudo o que vem depois como uma única string enorme e a contagem de colunas nunca se recupera. O `csvclean -n` informa a primeira linha em que o número de campos dá errado.
Um arquivo CSV pode ter quebras de linha dentro de um campo?
Pode. A RFC 4180 permite, desde que o campo esteja entre aspas, e qualquer analisador decente lida com isso. As linhas parecem se partir ao meio quando uma ferramenta divide por quebras de linha antes de considerar as aspas, o que descreve a maioria dos one-liners de shell e vários importadores de planilha. Use um analisador de CSV de verdade em vez de reparar o arquivo.
Como removo o BOM de um arquivo CSV?
No Linux, `sed -i '1s/^\xEF\xBB\xBF//' file.csv`; no macOS, o mesmo com `sed -i ''`. Só faça isso se algo adiante estiver engasgando com ele. O Excel usa o BOM para reconhecer um arquivo como UTF-8 quando você dá dois cliques, então removê-lo é o motivo de os acentos quebrarem para quem receber o arquivo depois.
Dá para reparar um CSV quebrado no celular?
Para problemas de delimitador e codificação, sim: um app que permita reabrir o arquivo com configurações de leitura explícitas resolve isso sem alterar um único byte. Um dano estrutural como uma aspa sem escape exige achar a linha com problema e editar aquela célula, o que é possível, mas trabalhoso; se mais do que algumas linhas estiverem erradas, exporte o arquivo de novo.

uos — Desenvolve o CSV Editor e o Smart CSV Viewer, então lê muitos arquivos CSV que os exportadores de outras pessoas geraram errado.