Cookies für Statistik und Werbung
Wir setzen Cookies für Statistik und Werbung ein, beides geht an Google. Wenn du ablehnst, ändert sich für dich sichtbar nichts.Zur Datenschutzseite
TSV kannst du hier kostenlos und ohne Konto in NDJSON umwandeln: Datei oben ablegen, und ein, zwei Sekunden später steht das Ergebnis zum Herunterladen bereit. Die Umwandlung läuft in deinem eigenen Browser, die Datei wird also nie hochgeladen — das klappt unter Windows, macOS und Linux ebenso wie auf iPhone und Android, und es funktioniert selbst dann noch, wenn du das Netz abschaltest.
Bis zu 100 Dateien auf einmal. Gemischte Formate sind kein Problem.
Sie werden nacheinander umgewandelt und kommen zusammen als ZIP zurück.
TSV in NDJSON
Datenjournalistische Teams, die aus einer Verwaltungsanfrage oder einem Opendata-Portal eine große tabgetrennte Liste bekommen — etwa Förderbescheide, Vergabeprotokolle oder eine Auswertung von Bundestagsdrucksachen —, wollen daraus meist eine durchsuchbare Rechercheplattform bauen, in der Kolleginnen und Kollegen nach Namen, Orten oder Beträgen filtern können.
Elasticsearch und OpenSearch, die üblichen Werkzeuge für so eine Volltextsuche, nehmen keine tabgetrennte Datei entgegen. Ihre Bulk-Schnittstelle liest ausschließlich zeilenweise abgelegte JSON-Dokumente, und genau dieses Format ist der erste Schritt zwischen der Rohdatei und der durchsuchbaren Datenbank.
Die Ausgabe besteht aus einem vollständigen JSON-Objekt pro Zeile — ohne öffnende Klammer, ohne Kommas zwischen den Zeilen, ohne schließende Klammer. Genau diese Abwesenheit macht das Format aus: Eine Importroutine liest eine Zeile, verarbeitet sie, verwirft sie wieder, ohne je die gesamte Datei im Speicher zu halten.
Das bedeutet auch, dass die Datei als Ganzes kein gültiges JSON ist — ein Parser, der ein Array erwartet, scheitert bereits an der zweiten Zeile. Das ist kein Fehler, sondern die Eigenschaft, die es erlaubt, eine Datei mit mehreren Millionen Zeilen mit begrenztem Arbeitsspeicher zu laden.
Die Kopfzeile liefert die Feldnamen exakt so, wie sie geschrieben sind. „Fördersumme (EUR)" bleibt „Fördersumme (EUR)", nichts wird umbenannt, weil eine stillschweigende Umbenennung die geladenen Dokumente nicht mehr mit der Ausgangsdatei vergleichbar machen würde.
Elasticsearch behandelt einen Punkt in einem Feldnamen als Pfadtrenner, und dasselbe gilt für die Punktnotation in MongoDB — eine Spalte namens „betrag.netto" erzeugt also ein verschachteltes Feld statt eines flachen und kurz darauf einen Mapping-Konflikt. Solche Spaltennamen vor der Umwandlung in der Kopfzeile zu bereinigen, ist eine Änderung; sie nachträglich in einer Million geladener Dokumente zu korrigieren, ist keine.
Die Ausgabe enthält ausschließlich Dokumente. Der `_bulk`-Endpunkt von Elasticsearch und OpenSearch verlangt vor jedem Dokument eine eigene Metadatenzeile, die die Operation benennt — ohne sie bricht der Import bereits an der zweiten Zeile mit einer wenig hilfreichen Fehlermeldung ab.
Ein einziger Durchlauf mit `jq -c '{index:{}}, .'` fügt diese Zeile vor jedem Dokument ein, danach nimmt die Schnittstelle die Datei entgegen. `mongoimport --type json` dagegen liest die Datei genau so, wie sie aus dieser Umwandlung herauskommt, ohne diesen Zwischenschritt.
Die Spalten, nach denen später gesucht wird, sind meist die unhandlichsten: Betreffzeilen, Begründungstexte, Protokollnotizen. In einer tabgetrennten Datei sind genau diese Felder das Risiko — ein eingefügter Tabulator verschiebt eine Spalte, ein Zeilenumbruch beendet die Zeile vorzeitig.
In JSON sind das gewöhnliche Zeichen einer Zeichenkette: Ein Tabulator wird als \t geschrieben, ein Zeilenumbruch als \n, und keines von beiden kann die Struktur eines Dokuments beeinflussen. Für eine Suchindexierung ist das der eigentliche Sicherheitsgewinn — der indizierte Text ist der vollständige Feldinhalt, nicht der Text bis zum ersten zufällig bedeutsamen Zeichen.
Werte, die wie Zahlen aussehen, werden zu JSON-Zahlen, „true" und „false" zu Booleans, alles andere bleibt Zeichenkette — eine tabgetrennte Datei kennt keine Typen, also wird geraten. Für Fördersummen und Fallnummern in numerischer Form ist das genau richtig und erspart eine spätere Mapping-Anpassung.
Für ein Aktenzeichen mit führender Null ist es das nicht: `00123` wird als Zahl 123 gelesen, und ein numerisch typisiertes Feld ist in Elasticsearch nicht analysiert, findet also keinen Treffer mehr für die ursprüngliche Zeichenkette bei einer Volltextsuche. Solche Spalten lassen sich vor der Umwandlung mit einem führenden Zeichen versehen oder danach in einem `jq`-Durchgang korrigieren.
Eine leere Zelle wird als `null` geschrieben, nicht als leere Zeichenkette, und Elasticsearch ignoriert `null` bei der Ableitung eines Feldtyps. Ist eine Spalte für die ersten paar tausend Dokumente durchgehend leer und erst danach numerisch, kann die automatische Zuordnung vom ersten tatsächlichen Wert abhängen — und ist dieser Wert ausnahmsweise ein Vermerk statt einer Zahl, schlägt die Indexierung für alle folgenden Dokumente dieses Feldes fehl.
Ein explizit definiertes Mapping vor dem Laden vermeidet das. Ein Blick mit `head -n 100` auf die konvertierte Datei zeigt schnell, welche Spalten dafür in Frage kommen.
Die Feldnamen kommen aus der Kopfzeile, jede spätere Zeile wird an ihr gemessen. Taucht in einer über Jahre gewachsenen Verwaltungsliste plötzlich eine zusätzliche Spalte auf, ohne dass die Kopfzeile angepasst wurde, bekommen die überzähligen Werte keinen eigenen Feldnamen, sondern landen gesammelt unter `__parsed_extra`, als Array, nur bei den betroffenen Zeilen.
Das macht eine solche Unstimmigkeit sichtbar, statt sie stillschweigend falsch zuzuordnen — ein zusammengesetzter Datensatz aus mehreren Verwaltungsjahren ist genau der Fall, in dem das häufiger vorkommt, als man erwartet.
BigQuery, Redshift und Snowflake lesen tabgetrennte Dateien direkt und laden sie schneller als JSON-Dokumente, weil kein Feldname pro Zeile geparst werden muss. Geht die Zieldatenbank ein bereits definiertes Tabellenschema entgegen, bringt diese Umwandlung keinen Vorteil.
Parquet ist die bessere Wahl, wenn dieselben Daten wiederholt abgefragt statt einmalig eingelesen werden, weil es Feldnamen einmal im Footer und die Werte typisiert in Spalten speichert. NDJSON hat seinen Platz genau dort, wo das Ziel wirklich dokumentenbasiert arbeitet — ein Suchindex, ein Dokumentenspeicher, eine zeilenweise lesende Import-Pipeline.
Sowohl das Lesen der tabgetrennten Datei als auch das Schreiben des NDJSON laufen als gewöhnliches JavaScript auf dieser Seite, es wird also keine Datei irgendwohin übertragen. Für eine Verwaltungsliste vor Veröffentlichung oder einen Datensatz, der Persönlichkeitsrechte berührt, ist das keine Nebensache.
Die Obergrenze liegt bei 100 MB je Datei und hundert Dateien pro Durchgang, und die gesamte Tabelle wird vollständig im Arbeitsspeicher aufgebaut. Für eine Datei über dieser Größe ist ein streamender Reader in einem eigenen Skript das richtige Werkzeug — und da das Ziel ohnehin ein Ladevorgang ist, ist so ein Skript häufig etwas, das früher oder später ohnehin geschrieben werden muss.
| TSV | NDJSON | |
|---|---|---|
| Vollständiger Name | Tab-Separated Values | Newline-Delimited JSON |
| Dateiendung | .tsv, .tab | .ndjson, .jsonl |
| Medientyp | text/tab-separated-values | application/x-ndjson |
| Erstmals veröffentlicht | 1993 | 2013 |
| Spezifikation | IANA text/tab-separated-values | — |
| Lizenzlage | Offener Standard | Offener Standard |
| Heutiger Stand | Aktuell | Aktuell |
| Öffnet im Browser | Kein Browser | Kein Browser |
| Stattdessen erwogen | CSV, JSON | JSON, CSV |
Es geht nichts verloren. TSV und NDJSON speichern ihren Inhalt verlustfrei — die Umwandlung tauscht die Verpackung, nicht die Qualität, und du kannst sie wiederholen, ohne dass sich Schäden aufsummieren.
pandas liest sowohl TSV als auch NDJSON — du kannst das Ergebnis also gegen das Original prüfen, ohne ein zweites Programm zu brauchen.
TSV wurde 1993 veröffentlicht. Festgehalten ist das in IANA text/tab-separated-values — lohnt sich zu kennen, wenn die Datei das Programm überleben soll, das sie geschrieben hat.
NDJSON stammt aus 2013. jq und pandas lesen das Format.
TSV wurde 1993 veröffentlicht, NDJSON 2013. Das ältere ist in der Regel die sicherere Datei zum Weitergeben, das jüngere erledigt dieselbe Aufgabe mit weniger Bytes.
Nein. Diese Umwandlung läuft vollständig in deinem Browser, die Datei verlässt dein Gerät also nicht. Du kannst das selbst nachprüfen: Öffne den Netzwerk-Tab der Entwicklerwerkzeuge und wandle etwas um. Zu sehen sind die Seite selbst und die Statistik- und Werbeanfragen, mit denen dieser Dienst bezahlt wird — und keine einzige, die deine Datei trägt.
Ja. Kein Konto, kein Wasserzeichen und kein Tageskontingent, das sich verbraucht — es läuft auf deinem eigenen Rechner, du darfst also so oft wiederkommen, wie du willst. Dateien bis 100 MB verarbeitet der Browser, 100 auf einmal.
Nein. NDJSON speichert denselben Inhalt, ohne etwas wegzuwerfen — das Ergebnis ist qualitativ mit dem Original identisch.
Es geht nichts verloren. TSV und NDJSON speichern ihren Inhalt verlustfrei — die Umwandlung tauscht die Verpackung, nicht die Qualität, und du kannst sie wiederholen, ohne dass sich Schäden aufsummieren.