Converter NDJSON para TSV

Aqui você converte NDJSON para TSV de graça e sem conta: solte o arquivo acima e em poucos segundos o resultado está pronto para baixar. A conversão acontece dentro do seu próprio navegador, então o arquivo nunca é enviado. Funciona igual no Windows, no macOS e no Linux e também no iPhone e no Android, e continua funcionando mesmo se você cortar a conexão.

  • Onde roda No seu navegador. O arquivo nunca é enviado.
  • Reconstruído TSV funciona de um jeito diferente de NDJSON. Não é a degradação gradual de um codec com perda: o que TSV consegue expressar é reproduzido fielmente, e o que não tem equivalente ali não sobrevive de jeito nenhum.
  • Limite de tamanho Até 100 MB por arquivo, de graça e sem conta.
  • Vale saber Objetos aninhados são achatados em colunas. Dados muito aninhados perdem a forma.

Até 100 arquivos de uma vez. Formatos misturados não são problema.

A tabulação ganha porque log é cheio de vírgula

Olhe o que um registro de evento de fato contém. Um caminho de requisição com string de consulta. Um user agent, que é só vírgula e parêntese. Uma mensagem de erro citando um valor. Um endereço postal. Mande isso para CSV e boa parte de cada linha fica entre aspas, porque o delimitador aparece dentro do dado em quase toda linha.

A tabulação quase nunca aparece dentro desses valores, então a maioria dos campos sai sem aspas e o arquivo continua posicional — a terceira coluna de fato fica entre o segundo e o terceiro caractere de tabulação. É essa propriedade que o resto desta página explica, e é também a propriedade que um punhado de campos pode tirar de você em silêncio.

Este TSV usa aspas como um CSV, e o cut não sabe disso

Vale ser exato sobre o que o gerador faz, porque o apelo inteiro de um arquivo separado por tabulação é que quem lê pode ser simples. Um valor contendo uma tabulação vem entre aspas duplas. Um valor contendo aspas duplas vem entre aspas, com as aspas internas duplicadas. Um valor contendo quebra de linha vem entre aspas. Todo o resto, vírgula incluída, é escrito como está.

Essa é a convenção da RFC 4180 com uma tabulação no lugar da vírgula, e não é a definição da IANA de valores separados por tabulação, que proíbe tabulação dentro de campos em vez de escapar. A consequência prática é que `cut -f4` e `awk -F$'\t'` funcionam até uma mensagem de log conter uma tabulação, e nesse momento aquela linha ganha um campo a mais e toda coluna depois da quarta desloca uma posição, só naquela linha. Nada dá erro. Se os seus campos podem carregar texto colado — e mensagem de log pode — valide antes de confiar numa leitura posicional, ou use um leitor que entenda aspas.

A ordem das colunas vem do arquivo NDJSON, não de um esquema

As colunas são a união de toda chave vista em qualquer lugar do arquivo, na ordem em que cada chave apareceu pela primeira vez. É a resposta certa para uma origem em que nada obriga a segunda linha a carregar as mesmas chaves da primeira, e é a coisa mais importante de entender antes de automatizar esta conversão.

Isso significa que a ordem das colunas é uma propriedade do dado, não do formato. Uma exportação noturna em que o primeiro registro de erro por acaso chega na linha 12 hoje e na linha 40.000 amanhã produz dois arquivos com colunas em ordens diferentes. O cabeçalho está certo nos dois. Um pipeline que lê pelo nome funciona; um que lê por posição está errado no segundo dia e não dá sinal nenhum disso.

Tornando uma etapa recorrente de NDJSON para TSV reproduzível

A correção é parar de deixar o arquivo decidir. Projete os registros para um conjunto fixo de chaves antes de converter — `jq -c '{ts, level, service, msg}'` dá a toda linha as mesmas quatro chaves na mesma ordem, e a conversão passa a ter só um layout de coluna possível, seja o que for que a origem continha.

Isso também resolve o problema da tabela larga e esparsa ao mesmo tempo. Uma exportação de eventos misturados convertida inteira produz uma coluna para todo campo que qualquer tipo de evento já carregou, a maioria vazia na maioria das linhas; projetar antes dá uma tabela estreita sem célula vazia. Se não puder projetar, ao menos valide: leia a linha de cabeçalho no pipeline e falhe alto se não for a esperada, em vez de deixar `cut -f3` devolver o campo errado por um mês.

Campo aninhado do registro vira coluna TSV com ponto

Log estruturado costuma aninhar — um objeto `request` com método e caminho, um objeto `user` com identificador, um bloco `context` com id de rastreio. Cada folha ganha uma coluna nomeada pelo caminho: `request.method`, `user.id`, `context.trace_id`. Uma coluna por valor de folha, sem exceção.

Um ponto no nome de coluna é inofensivo para `cut` e `awk`, que nunca olham o cabeçalho, e incômodo em qualquer outro lugar: precisa de aspas em SQL, e não é um identificador válido na maioria dos carregadores. Se o TSV vai para uma tabela, renomeie na etapa de projeção em vez de depois — `jq -c '{method: .request.method}'` produz o nome de coluna que você quer e evita um ALTER depois.

Carregando o TSV no PostgreSQL, DuckDB ou SQLite

O PostgreSQL é o que precisa de cuidado, porque o formato de texto padrão do `COPY` dele usa escape de barra invertida em vez de aspas e vai ler um campo entre aspas ao pé da letra, aspas incluídas. A forma que combina com o que foi gravado é `\copy events FROM 'out.tsv' WITH (FORMAT csv, DELIMITER E'\t', HEADER true)` — regras de CSV, delimitador de tabulação.

O DuckDB lê com `read_csv('out.tsv', delim='\t', header=true)` e infere tipos por amostra, o que é conveniente e também é como uma coluna de identificador perde o zero à esquerda; passe um mapa `types` explícito para o que precisa continuar texto. O `.import --csv` do SQLite precisa do separador ajustado antes com `.separator "\t"`. Nos três, o campo vazio chega como string vazia em vez de NULL a menos que você diga o contrário, o que é o problema da próxima seção.

Campo vazio esconde a diferença entre nulo e em branco

Um null do JSON e uma string vazia do JSON viram os dois nada entre duas tabulações, e não tem como diferenciar depois. Nenhum dos casos é o gerador sendo descuidado — um arquivo de texto delimitado não tem um terceiro estado onde colocar isso.

Se importa depende da pergunta que você está fazendo. Contar quantos eventos não tinham `user_id` é uma consulta diferente de contar quantos tinham um vazio, e depois desta conversão as duas dão a mesma resposta. Se a distinção é importante, codifique ela antes de converter — `jq -c '.user_id //= "«nulo»"'` é feio e inequívoco — ou mande a exportação para Parquet, onde nulo é um estado real e a coluna mantém o tipo.

Quanto texto uma exportação NDJSON vira

Geralmente menos do que era. Cada linha da origem repete o nome das próprias chaves; o TSV escreve elas uma vez no cabeçalho e depois só os valores, então um conjunto de registro estreito costuma encolher bastante. Um conjunto largo e esparso vai na direção contrária, porque toda linha precisa carregar uma tabulação para cada coluna, inclusive as que não têm nada.

O teto gratuito é de 100 MB por arquivo, e a exportação inteira é lida em registros antes de as colunas poderem ser resolvidas, então memória, não o limite, é o que você encontra primeiro. O NDJSON divide com segurança em qualquer fronteira de linha, então `split -l 500000` dá arquivos que convertem limpos cada um — mas repare que arquivos divididos convertidos separadamente podem discordar sobre a ordem das colunas pelo mesmo motivo de cima, mais um argumento para projetar antes.

Quando um destino diferente ganha do TSV para esta exportação

Se uma pessoa vai abrir isso, mande para CSV ou XLSX em vez disso — uma planilha lida com um CSV sem precisar ser avisada do separador, e uma pasta de trabalho mantém a coluna de identificador como texto. Se vai para um data warehouse ou vai ficar guardado, o Parquet é menor, tipado e não tem problema de ordem de coluna nenhum.

O TSV ganha o lugar dele numa situação só: o destino é um programa que separa por um caractere, e você quer o arquivo legível com `head` enquanto monta o comando. É uma situação real e comum. Não é a mesma coisa que «eu preciso disso no Excel», e escolher TSV por esse motivo é como as pessoas acabam com um arquivo que a planilha importa numa coluna só.

O NDJSON é convertido aqui e não vai a lugar nenhum

JavaScript puro nesta aba. Sem envio, sem download de motor, sem conta, sem cota diária — e a aba de rede durante uma conversão é como confirmar isso, em vez de aceitar esta frase como prova.

Exportação de evento de produção é o material para o qual este par existe, e carrega endereço IP, identificador de sessão, caminho de requisição e user agent. Alimentar isso a um conversor hospedado é uma transferência de dado a um terceiro, seja o que for que o conversor prometa. Aqui não há transferência para se preocupar.

Como converter NDJSON para TSV

  1. Solte o seu arquivo NDJSON nesta página, ou clique para escolher um.
  2. Escolha TSV como destino. A conversão acontece no seu navegador e o arquivo não é enviado.
  3. Baixe o arquivo TSV pronto.

NDJSON ou TSV: o que muda

NDJSON comparado com TSV
NDJSONTSV
Nome completoNewline-Delimited JSONTab-Separated Values
Extensão do arquivo.ndjson, .jsonl.tsv, .tab
Tipo de mídiaapplication/x-ndjsontext/tab-separated-values
Publicado pela primeira vez20131993
EspecificaçãoIANA text/tab-separated-values
LicençaPadrão abertoPadrão aberto
Situação hojeAtualAtual
Abre no navegadorNenhum navegadorNenhum navegador
Considerado no lugarJSON, CSVCSV, JSON

Abrir o resultado

pandas lê tanto NDJSON quanto TSV, então dá para comparar o resultado com o original sem um segundo programa.

Para que serve cada formato

TSV e de 1993, descrito em IANA text/tab-separated-values. Microsoft Excel, LibreOffice Calc e pandas leem o formato.

TSV foi publicado em 1993 e NDJSON em 2013. O mais antigo costuma ser o arquivo mais seguro para entregar; o mais novo faz o mesmo com menos bytes.

De NDJSON para TSV: perguntas frequentes

Meu arquivo NDJSON é enviado para algum lugar?

Não. Esta conversão acontece inteiramente no seu navegador, então o arquivo não sai do seu aparelho. Você mesmo pode conferir: abra a aba de rede das ferramentas de desenvolvedor e converta alguma coisa. Você verá a própria página e as requisições de estatística e de publicidade com que este serviço é pago, e nenhuma que leve o seu arquivo.

Converter NDJSON para TSV é grátis?

É. Sem conta, sem marca d’água e sem cota diária para gastar: roda no seu próprio aparelho, então você pode voltar quantas vezes quiser. O navegador processa arquivos de até 100 MB, 100 por vez.

Perde qualidade ao converter NDJSON para TSV?

NDJSON e TSV descrevem o conteúdo de maneiras radicalmente diferentes. A conversão é, portanto, uma reconstrução e não uma cópia: fiel, mas não idêntica byte a byte. Objetos aninhados são achatados em colunas. Dados muito aninhados perdem a forma.

Preciso instalar alguma coisa para abrir um arquivo TSV?

Para a conversão, não: ela acontece no navegador que você já tem aberto. Para abrir o resultado você precisa depois do programa com que o seu aparelho normalmente exibe Tab-Separated Values.

Mais sobre esses formatos