Convertir NDJSON a TSV

Aquí puedes convertir NDJSON a TSV gratis y sin cuenta: suelta el archivo arriba y en un par de segundos tienes el resultado listo para descargar. La conversión ocurre en tu propio navegador, así que el archivo no se sube nunca. Funciona igual en Windows, macOS y Linux que en iPhone y Android, y sigue funcionando aunque cortes la conexión.

  • Dónde se ejecuta En tu navegador. El archivo no se sube.
  • Reconstruido TSV funciona de otra manera que NDJSON. No es la degradación gradual de un códec con pérdida: lo que TSV puede expresar se reproduce fielmente, y lo que no tiene equivalente allí no sobrevive en absoluto.
  • Límite de tamaño Hasta 100 MB por archivo, gratis y sin cuenta.
  • Conviene saberlo Los objetos anidados se aplanan en columnas. Los datos muy anidados pierden su forma.

Hasta 100 archivos a la vez. Mezclar formatos no es problema.

El tabulador gana porque los datos de registro están llenos de comas

Mira qué contiene de verdad un registro de evento. Una ruta con su cadena de consulta. Un identificador de navegador, que no es más que comas y paréntesis. Un mensaje de error citando un valor. Una dirección postal, donde la coma separa la calle del número y el número del piso. Manda eso a un CSV y una parte enorme de cada fila acaba entre comillas, porque el delimitador aparece dentro de los datos en casi todas las líneas.

Los tabuladores no aparecen prácticamente nunca dentro de esos valores, así que la mayoría de campos se escriben desnudos y el archivo sigue siendo posicional: la columna tres está de verdad entre el segundo y el tercer tabulador. Esa es la propiedad de la que trata el resto de la página, y también la que un puñado de campos te puede quitar sin avisar.

Este TSV se entrecomilla como un CSV, y cut no lo sabe

Conviene ser exacto con lo que hace el escritor, porque toda la gracia de un archivo separado por tabuladores es que quien lo lee puede ser rudimentario. Un valor que contiene un tabulador se envuelve entre comillas dobles. Un valor que contiene una comilla doble se envuelve, y la comilla interior se dobla. Un valor que contiene un salto de línea se envuelve. Todo lo demás, comas incluidas, se escribe tal cual.

Es la convención de un CSV con el tabulador en el papel de la coma, y no es la definición formal de «valores separados por tabuladores», que prohíbe el tabulador dentro de un campo en lugar de escaparlo. La consecuencia práctica es que cortar por el cuarto campo funciona hasta que un mensaje de registro contiene un tabulador; a partir de esa fila, y solo en esa fila, hay una columna de más y todo lo posterior se desplaza. Nada da error. Si tus campos pueden llevar texto pegado por una persona —y los mensajes de error lo llevan—, valida antes de fiarte de una lectura por posición o usa un lector que entienda comillas.

El orden de las columnas lo decide el archivo, no un esquema

Las columnas son la unión de todas las claves que aparecen en cualquier punto del archivo, en el orden en que cada una se vio por primera vez. Es la respuesta correcta para un origen en el que nada obliga a la segunda línea a traer las claves de la primera, y es lo más importante que hay que entender antes de automatizar esta conversión.

Significa que el orden de columnas es una propiedad de los datos y no del formato. Una exportación nocturna en la que el primer registro de error aparece hoy en la línea 12 y mañana en la 40.000 produce dos archivos con las columnas en distinto orden. La fila de cabecera es correcta en los dos. Un proceso que lee por nombre no se entera; uno que lee por posición está equivocado desde el segundo día y no da ninguna señal.

Cómo volver reproducible una conversión que se repite cada noche

La solución consiste en dejar de permitir que decida el archivo. Proyecta los registros a un juego fijo de claves antes de convertir: recorrer el NDJSON con jq y quedarte con las cuatro o cinco claves que te interesan, en el mismo orden siempre, deja a la conversión una sola disposición posible de columnas pase lo que pase en el origen.

Eso resuelve al mismo tiempo el problema de la tabla ancha y vacía. Una exportación con eventos de varios tipos convertida entera produce una columna por cada campo que cualquier tipo de evento haya llevado alguna vez, la mayoría vacías en la mayoría de filas; proyectando antes obtienes una tabla estrecha y sin huecos. Si no puedes proyectar, al menos comprueba: lee la línea de cabecera dentro del proceso y falla ruidosamente si no es la que esperabas, en lugar de dejar que una lectura por posición devuelva el campo equivocado durante un mes.

Lo anidado se convierte en columnas con puntos en el nombre

Los registros estructurados anidan: un objeto de petición con su método y su ruta, un objeto de usuario con un identificador, un bloque de contexto con una traza. Cada hoja recibe una columna llamada como su ruta, con los tramos separados por puntos, y los índices de un arreglo cuentan como tramos. Una columna por valor final, sin excepciones.

Ese aplanado se aplica al ir hacia CSV, TSV, SQL, INI, XLSX y Parquet, y no se aplica al escribir JSON, YAML, TOML, XML ni NDJSON, que conservan el árbol. Un punto en el nombre de columna es inofensivo para las herramientas que parten por un carácter, porque nunca miran la cabecera, e incómodo en todo lo demás: hay que entrecomillarlo en SQL y no es un identificador válido en muchos cargadores. Si el TSV va a acabar en una tabla, renombra durante la proyección y no después, que ahorra una alteración de esquema más tarde.

El punto decimal del JSON llega intacto y tu hoja de cálculo no lo espera

Un número en JSON se escribe con punto decimal por definición del formato; no hay otra manera de escribirlo. Aquí ese valor no se reformatea ni se localiza: sale al TSV exactamente como venía, de modo que un importe de 1234.56 sigue siendo 1234.56 en el archivo. Eso es lo correcto y es también la trampa.

Abre ese TSV en una hoja de cálculo configurada para España o para casi cualquier país hispanohablante y la columna deja de ser numérica, porque ahí el separador decimal es la coma. Según la versión y la configuración, el valor se queda como texto alineado a la izquierda o, peor, algo con pinta de fecha se convierte en una fecha. La solución no es tocar el archivo: es decirle al lector cuál es la convención en el momento de importar —en el asistente de importación, o con la opción de punto decimal correspondiente si el destino es R o pandas—. Sustituir puntos por comas en masa reescribiría además cualquier punto que hubiera dentro de las columnas de texto.

Los ceros a la izquierda salen bien de aquí y se pierden después

Merece la pena distinguir este par de su vecino, el que convierte un CSV a TSV, porque se comportan distinto y la diferencia es útil. Allí el archivo se analiza como tabla y todo lo que parece un número se lee como número, con lo que un código postal como 08001 pierde su cero. Aquí no ocurre: cada línea se interpreta como JSON, y si el origen declaró esa clave como cadena, cadena sigue siendo. El TSV recibe 08001 con su cero delante.

Lo que no puede hacer el archivo es defenderse de lo que venga después. Un texto delimitado no distingue el número 7 de la cadena «7», así que el cargador de destino volverá a adivinar el tipo por su cuenta y ahí es donde se pierde el cero, se convierte un DNI en notación científica o un identificador largo se redondea. Si el destino permite declarar los tipos de columna, decláralos; es la única defensa real, y es más barata que descubrirlo con la tabla cargada.

El nulo y la cadena vacía se vuelven la misma nada

Un null de JSON y una cadena vacía de JSON acaban los dos como nada entre dos tabuladores, y después no hay forma de distinguirlos. Tampoco es que el escritor sea descuidado: un archivo de texto delimitado no tiene un tercer estado en el que ponerlos.

Que importe depende de la pregunta que vayas a hacer. Contar cuántos eventos no traían identificador de usuario es una consulta distinta de contar cuántos lo traían vacío, y después de esta conversión las dos dan el mismo resultado. Si la distinción sostiene algo, codifícala antes de convertir con un valor centinela feo y sin ambigüedad, o manda la exportación a Parquet, donde el nulo es un estado real y la columna conserva su tipo.

Cargarlo en PostgreSQL, DuckDB o SQLite

PostgreSQL es el que exige cuidado, porque su formato de copia por defecto usa escapes con barra invertida en lugar de comillas y leería un campo entrecomillado de forma literal, comillas incluidas. Lo que encaja con lo que se ha escrito aquí es pedirle explícitamente el formato CSV con el tabulador como delimitador y la primera fila como cabecera; con eso las reglas de entrecomillado coinciden y no hay sorpresas.

DuckDB lo lee indicando el delimitador y la cabecera, e infiere los tipos a partir de una muestra, cosa muy cómoda y que es también la manera de que una columna de identificadores pierda sus ceros iniciales: pásale un mapa de tipos explícito para todo lo que deba seguir siendo texto. SQLite necesita fijar antes el separador y después importar. En los tres, un campo vacío llega como cadena vacía y no como nulo mientras no digas lo contrario, que es justo el problema de la sección anterior visto desde el otro extremo.

La cuenta de filas frente a la cuenta de líneas

Las líneas en blanco se saltan, incluida la que casi todo el mundo deja al final del archivo, así que el número de filas de datos es el de líneas con contenido; súmale una por la cabecera para comparar con lo que te diga un contador de líneas. Es una comprobación de treinta segundos y detecta la mitad de los problemas de una exportación.

Una línea que no sea JSON válido no se descarta en silencio: detiene la conversión indicando el número de línea. Es deliberado y es lo que quieres en un proceso automatizado, porque una exportación truncada a mitad de escritura produce exactamente eso —una última línea incompleta—, y convertirla sin más te daría un archivo con una fila menos y ninguna señal de que faltaba algo.

Cuánto texto sale y dónde está el techo de verdad

Normalmente menos del que entró. Cada línea del origen repite los nombres de sus claves; el TSV los escribe una sola vez en la cabecera y a partir de ahí solo valores, de modo que un conjunto estrecho de registros suele encoger de forma apreciable. Uno ancho y disperso va en la otra dirección, porque cada fila tiene que llevar un tabulador por cada columna, incluidas aquellas en las que no tiene nada.

El techo formal son 100 MB por archivo, y lo que te encuentras primero es la memoria: para saber cuáles son las columnas hay que haber leído todos los registros, así que la tabla entera existe a la vez antes de escribir nada. Un NDJSON se puede partir con seguridad por cualquier salto de línea, y trocearlo produce archivos que convierten limpiamente cada uno; ten en cuenta que los trozos convertidos por separado pueden discrepar en el orden de columnas por el motivo de más arriba, que es un argumento más para proyectar primero.

Se convierte en esta pestaña y no se envía a ninguna parte

JavaScript corriente dentro de esta página. No hay subida, ni descarga de ningún motor, ni cuenta, ni cupo diario; y la pestaña de red del navegador durante una conversión es la forma de comprobarlo en lugar de creerse esta frase. Las líneas se separan además con un único salto de línea y no con la pareja de Windows, que es lo que esperan una tubería de shell, una diferencia de Git, R y pandas.

Las exportaciones de producción son el material para el que existe este par, y llevan direcciones IP, identificadores de sesión, rutas de petición e identificadores de navegador. Entregar una a un conversor alojado es una comunicación de datos a un tercero, prometa lo que prometa ese conversor y esté donde esté su servidor. Aquí no hay ninguna comunicación sobre la que razonar.

Cómo convertir NDJSON a TSV

  1. Suelta tu archivo NDJSON en esta página, o haz clic para elegir uno.
  2. Elige TSV como destino. La conversión ocurre en tu navegador y el archivo no se sube.
  3. Descarga el archivo TSV terminado.

NDJSON frente a TSV: qué cambia

NDJSON frente a TSV
NDJSONTSV
Nombre completoNewline-Delimited JSONTab-Separated Values
Extensión de archivo.ndjson, .jsonl.tsv, .tab
Tipo de medioapplication/x-ndjsontext/tab-separated-values
Publicado por primera vez20131993
EspecificaciónIANA text/tab-separated-values
LicenciaEstándar abiertoEstándar abierto
Situación actualVigenteVigente
Se abre en el navegadorNingún navegadorNingún navegador
Considerado en su lugarJSON, CSVCSV, JSON

Abrir el resultado

pandas lee tanto NDJSON como TSV, así que puedes comparar el resultado con el original sin un segundo programa.

Para qué sirve cada formato

TSV es de 1993, recogido en IANA text/tab-separated-values. Microsoft Excel, LibreOffice Calc y pandas lo leen.

TSV se publicó en 1993 y NDJSON en 2013. El más antiguo suele ser el archivo más seguro para entregar; el más reciente hace lo mismo con menos bytes.

De NDJSON a TSV: preguntas frecuentes

¿Se sube a algún sitio mi archivo NDJSON?

No. Esta conversión ocurre por completo en tu navegador, así que el archivo no sale de tu dispositivo. Puedes comprobarlo tú: abre la pestaña de red de las herramientas de desarrollo y convierte algo. Verás la propia página y las peticiones de estadística y publicidad con las que se paga este servicio, y ni una sola que lleve tu archivo.

¿Convertir NDJSON a TSV es gratis?

Sí. Sin cuenta, sin marca de agua y sin cupo diario que se gaste: se ejecuta en tu propio equipo, así que puedes volver tantas veces como quieras. El navegador procesa archivos de hasta 100 MB, 100 a la vez.

¿Se pierde calidad al convertir NDJSON a TSV?

NDJSON y TSV describen el contenido de maneras radicalmente distintas. La conversión es por tanto una reconstrucción y no una copia: fiel, pero no idéntica byte a byte. Los objetos anidados se aplanan en columnas. Los datos muy anidados pierden su forma.

¿Tengo que instalar algo para abrir un archivo TSV?

Para la conversión no: ocurre en el navegador que ya tienes abierto. Para abrir el resultado necesitas después el programa con el que tu dispositivo muestra normalmente Tab-Separated Values.

Más sobre estos formatos