NDJSON naar TSV omzetten

Hier zet je NDJSON naar TSV om, gratis en zonder account: sleep het bestand hierboven erin en binnen een paar seconden staat het resultaat klaar om te downloaden. De omzetting gebeurt binnen je eigen browser, dus het bestand wordt nooit geüpload. Het werkt hetzelfde op Windows, macOS en Linux als op iPhone en Android, en het blijft werken als je de verbinding verbreekt.

  • Waar het draait In je browser. Het bestand wordt nooit geüpload.
  • Opnieuw opgebouwd TSV werkt anders dan NDJSON. Het is dus niet het geleidelijke kwaliteitsverlies van een lossy codec: wat TSV kan uitdrukken wordt getrouw weergegeven, en wat daar geen equivalent heeft blijft helemaal weg.
  • Maximale grootte Tot 100 MB per bestand, gratis en zonder account.
  • Goed om te weten Geneste objecten worden platgeslagen tot kolommen. Diep geneste gegevens verliezen hun vorm.

Tot 100 bestanden tegelijk. Verschillende formaten door elkaar is prima.

De tab wint omdat logdata vol komma’s zit

Kijk wat een event-record werkelijk bevat. Een verzoekpad met een querystring. Een user agent, die vrijwel alleen komma’s en haakjes bevat. Een foutmelding die een waarde citeert. Een postadres. Stuur dat naar CSV en een groot deel van elke rij zit tussen aanhalingstekens, want de scheider komt in bijna elke regel voor in de data zelf.

Tabs komen bijna nooit in die waarden voor, dus blijven de meeste velden kaal en het bestand blijft positioneel — kolom drie zit echt tussen het tweede en derde tabteken. Dat is de eigenschap waar de rest van deze pagina over gaat, en het is ook de eigenschap die een handvol velden je stilletjes kunnen afnemen.

Deze TSV is aangehaald als een CSV, en dat weet cut niet

Het is de moeite waard om exact te zijn over wat de schrijver doet, want de hele aantrekkingskracht van een tabgescheiden bestand is dat de lezende tools grof mogen zijn. Een waarde met een tab erin wordt tussen dubbele aanhalingstekens gezet. Een waarde met een aanhalingsteken erin wordt aangehaald, met de interne aanhalingstekens verdubbeld. Een waarde met een nieuwe regel wordt aangehaald. Al het andere, komma’s inbegrepen, wordt geschreven zoals het is.

Dat is de RFC 4180-conventie met een tab in plaats van een komma, en het is niet de IANA-definitie van tabgescheiden waarden, die tabs binnen velden verbiedt in plaats van ze te ontsnappen. Het praktische gevolg is dat `cut -f4` en `awk -F$'\t'` correct zijn tot een logregel een tab bevat, waarna die rij een veld extra krijgt en elke kolom erna één opschuift, alleen op die rij. Niets geeft een fout. Kunnen je velden geplakte tekst bevatten — en dat kan bij logregels — valideer dan voor je een positionele lezing vertrouwt, of gebruik een lezer die aanhalingstekens begrijpt.

De kolomvolgorde komt uit het NDJSON-bestand, niet uit een schema

De kolommen zijn de vereniging van elke sleutel die ergens in het bestand voorkomt, in de volgorde waarin elke sleutel voor het eerst verscheen. Dat is het juiste antwoord voor een bron waar niets de tweede regel verplicht om dezelfde sleutels als de eerste te dragen, en het is het belangrijkste om te begrijpen voor je deze omzetting automatiseert.

Het betekent dat de kolomvolgorde een eigenschap van de data is en niet van het formaat. Een nachtelijke export waarin het eerste foutrecord vandaag op regel 12 staat en morgen op regel 40.000, levert twee bestanden op met kolommen in andere volgorde. De headerregel klopt in beide. Een pijplijn die op naam leest werkt prima; een die op positie leest is de tweede dag verkeerd en geeft geen enkel signaal.

Een terugkerende NDJSON-naar-TSV-stap reproduceerbaar maken

De oplossing is stoppen met het bestand laten beslissen. Projecteer de records naar een vaste sleutelset voor het omzetten — `jq -c '{ts, level, service, msg}'` geeft elke regel dezelfde vier sleutels in dezelfde volgorde, en de omzetting heeft dan nog maar één mogelijke kolomindeling ongeacht wat de bron bevatte.

Dat lost meteen ook het brede-en-schaarse probleem op. Een gemengde export in zijn geheel omgezet levert een kolom op voor elk veld dat elk eventtype ooit droeg, meestal leeg; eerst projecteren geeft een smalle tabel zonder lege cellen. Kun je niet projecteren, controleer dan minstens: lees de headerregel in de pijplijn en faal luid als hij niet is wat je verwachtte, in plaats van `cut -f3` een maand lang het verkeerde veld te laten teruggeven.

Geneste velden worden gestippelde TSV-kolommen

Gestructureerde logs zijn genest — een `request`-object met een methode en een pad, een `user`-object met een identifier, een `context`-blok met een trace-id. Elke bladwaarde krijgt een kolom vernoemd naar zijn pad: `request.method`, `user.id`, `context.trace_id`. Eén kolom per bladwaarde, zonder uitzonderingen.

Een punt in een kolomnaam is onschuldig voor `cut` en `awk`, die nooit naar de header kijken, en lastig overal elders: het moet worden aangehaald in SQL, en het is geen geldige identifier in de meeste laders. Gaat de TSV een tabel in, hernoem dan tijdens het projecteren in plaats van achteraf — `jq -c '{method: .request.method}'` geeft de kolomnaam die je wilt en bespaart later een ALTER.

De TSV laden in PostgreSQL, DuckDB of SQLite

PostgreSQL vraagt om de meeste zorg, want de standaard tekstindeling van `COPY` gebruikt backslash-escapes in plaats van aanhalingstekens en leest een aangehaald veld letterlijk in, aanhalingstekens en al. De vorm die past bij wat er geschreven is, is `\copy events FROM 'out.tsv' WITH (FORMAT csv, DELIMITER E'\t', HEADER true)` — CSV-regels, tab als scheider.

DuckDB leest het met `read_csv('out.tsv', delim='\t', header=true)` en leidt typen af uit een steekproef, wat handig is en ook hoe een kolom identifiers zijn leidende nullen kwijtraakt; geef een expliciete `types`-kaart voor alles dat tekst moet blijven. SQLite’s `.import --csv` heeft de scheider vooraf nodig met `.separator "\t"`. In alle drie komt het lege veld aan als lege tekst in plaats van NULL tenzij je anders zegt, wat het probleem van de volgende sectie is.

Lege velden verbergen het verschil tussen null en leeg

Een JSON-null en een lege JSON-tekst worden beide niets tussen twee tabs, en er is achteraf geen manier om ze te onderscheiden. Geen van beide is de schrijver die slordig is — een tekstbestand met scheidingstekens heeft geen derde toestand om ze in te plaatsen.

Of dat ertoe doet hangt af van de vraag die je stelt. Tellen hoeveel events geen `user_id` hadden is een andere vraag dan tellen hoeveel er een lege hadden, en na deze omzetting geven beide hetzelfde antwoord. Doet het onderscheid ertoe, codeer het dan voor het omzetten — `jq -c '.user_id //= "«null»"'` is lelijk en ondubbelzinnig — of stuur de export naar Parquet, waar null een echte toestand is en de kolom zijn type behoudt.

Hoeveel tekst een NDJSON-export wordt

Meestal minder dan het was. Elke regel van de bron herhaalt zijn sleutelnamen; de TSV schrijft ze één keer in de header en daarna alleen de waarden, dus een smalle recordset krimpt vaak merkbaar. Een brede, schaarse gaat de andere kant op, want elke rij moet een tab dragen voor elke kolom inclusief die waar hij niets in heeft.

De gratis grens is 100 MB per bestand en de hele export wordt in records ingelezen voor de kolommen bepaald kunnen worden, dus geheugen is eerder een grens dan de limiet zelf. NDJSON splitst veilig op elke regelgrens, dus `split -l 500000` geeft bestanden die elk schoon omzetten — maar bedenk dat apart omgezette gesplitste bestanden het over de kolomvolgorde oneens kunnen zijn, precies om de reden hierboven, wat weer een argument is om eerst te projecteren.

Wanneer een ander doel beter is dan TSV voor deze export

Gaat een mens het openen, stuur het dan naar CSV of XLSX in plaats van — een spreadsheet verwerkt een CSV zonder dat je moet zeggen wat de scheider is, en een werkmap houdt identifierkolommen als tekst. Gaat het naar een warehouse of wordt het bewaard, dan is Parquet kleiner, getypeerd en heeft het helemaal geen kolomvolgordeprobleem.

TSV verdient zijn plek in precies één situatie: de bestemming is een programma dat op een teken splitst, en je wilt het bestand met `head` kunnen lezen terwijl je het commando bouwt. Dat is een echte en veelvoorkomende situatie. Het is niet hetzelfde als "ik heb dit nodig in Excel", en TSV daarvoor kiezen is hoe mensen eindigen met een bestand dat hun spreadsheet in één kolom importeert.

De NDJSON wordt hier omgezet en nergens naartoe gestuurd

Gewoon JavaScript in dit tabblad. Geen upload, geen engine om te downloaden, geen account, geen dagelijkse limiet — en het netwerktabblad tijdens een omzetting is hoe je dat bevestigt in plaats van deze zin te geloven.

Productie-event-exports zijn het materiaal waarvoor dit paar bestaat, en ze dragen IP-adressen, sessie-ID’s, verzoekpaden en user agents. Zo’n export naar een hostende omzetter sturen is een gegevensoverdracht naar een derde partij, wat de omzetter ook belooft. Hier valt er niets te redeneren over overdracht.

Zo zet je NDJSON naar TSV om

  1. Sleep je NDJSON-bestand op deze pagina, of klik om er een te kiezen.
  2. Kies TSV als doel. De omzetting gebeurt in je browser en het bestand wordt niet geüpload.
  3. Download het klare TSV-bestand.

NDJSON of TSV: wat er verandert

NDJSON vergeleken met TSV
NDJSONTSV
Volledige naamNewline-Delimited JSONTab-Separated Values
Bestandsextensie.ndjson, .jsonl.tsv, .tab
Mediatypeapplication/x-ndjsontext/tab-separated-values
Voor het eerst gepubliceerd20131993
SpecificatieIANA text/tab-separated-values
LicentieOpen standaardOpen standaard
Stand van zakenActueelActueel
Opent in een browserGeen browserGeen browser
In plaats daarvan overwogenJSON, CSVCSV, JSON

Het resultaat openen

pandas leest zowel NDJSON als TSV, dus je kunt het resultaat naast het origineel leggen zonder een tweede programma.

Waarvoor elk formaat bedoeld is

TSV stamt uit 1993, vastgelegd in IANA text/tab-separated-values. Microsoft Excel, LibreOffice Calc en pandas lezen het formaat.

TSV verscheen in 1993 en NDJSON in 2013. Het oudste is doorgaans het veiligste bestand om te overhandigen; het nieuwste doet hetzelfde werk met minder bytes.

Van NDJSON naar TSV: veelgestelde vragen

Wordt mijn NDJSON-bestand ergens heen geüpload?

Nee. Deze omzetting gebeurt volledig in je browser, dus het bestand verlaat je apparaat niet. Je kunt het zelf nagaan: open het netwerktabblad van de ontwikkelaarshulpmiddelen en zet iets om. Je ziet de pagina zelf en de verzoeken voor statistiek en advertenties waarmee deze dienst betaald wordt, en geen enkel verzoek dat je bestand meeneemt.

Is NDJSON naar TSV omzetten gratis?

Ja. Geen account, geen watermerk en geen dagtegoed dat opraakt: het draait op je eigen machine, dus je mag zo vaak terugkomen als je wilt. De browser verwerkt bestanden tot 100 MB, 100 tegelijk.

Gaat er kwaliteit verloren bij het omzetten van NDJSON naar TSV?

NDJSON en TSV beschrijven de inhoud op fundamenteel andere manieren. De omzetting is daarom een reconstructie en geen kopie: getrouw, maar niet byte voor byte identiek. Geneste objecten worden platgeslagen tot kolommen. Diep geneste gegevens verliezen hun vorm.

Moet ik iets installeren om een TSV-bestand te openen?

Voor de omzetting niet: die gebeurt in de browser die je al open hebt staan. Om het resultaat te openen heb je daarna het programma nodig waarmee je apparaat Tab-Separated Values normaal weergeeft.

Meer over deze formaten