JSON Lines(JSONL)⇔ JSON 陣列 互相轉換

在每行一個 JSON 物件的 JSON Lines 格式與普通 JSON 陣列之間互相轉換,方便檢視機器學習資料集和日誌輸出。

什麼是 JSON Lines(JSONL)

JSON Lines 是每行寫一個 JSON 物件的格式。整份檔案本身並非 JSON,因此不需要處理結尾逗號,只要追加一行就能新增資料。應用日誌、機器學習訓練資料、匯入 BigQuery 或 Elasticsearch 等「一筆一筆流動」的用途廣泛採用此格式,副檔名通常是 .jsonl 或 .ndjson。

本工具可在 JSON Lines 與 JSON 陣列之間雙向轉換。從 JSONL 轉為陣列時會跳過空行,若某行不是有效的 JSON 則以錯誤告知。反向轉換時,最外層必須是陣列,否則會失敗。所有處理都在瀏覽器內完成,日誌或訓練資料這類不想外送的內容也能安心處理。

轉換 JSONL 與 JSON 陣列的步驟

  1. 選擇轉換方向 從 JSONL 轉為 JSON 陣列,或從 JSON 陣列轉為 JSONL。
  2. 貼上資料 JSONL 請以一行一物件,陣列請直接貼上以 [ 開頭的文字。
  3. 出現錯誤時檢查該行 訊息會指出哪一行無法解析。結尾多餘的逗號或未閉合的引號是常見原因。
  4. 複製結果 可直接存成檔案,或交給流程中的下一個工具。

用好本工具的小技巧

  • JSON Lines(JSONL)是每行排列一個獨立 JSON 物件的格式,廣泛用於 OpenAI 微調資料集以及 Elasticsearch/Logstash 的日誌輸出等場景。
  • 在"JSONL → JSON 陣列"模式下,每一行都必須是可單獨解析的 JSON 物件,空行會被自動跳過。
  • 在"JSON 陣列 → JSONL"模式下,整個輸入必須是一個 JSON 陣列([ ... ]),陣列中的每個元素會作為一行 JSONL 輸出。
  • 將大型日誌檔案從 JSONL 轉換為 JSON 陣列後,用 jq 命令或各程式語言的標準 JSON 陣列解析器處理起來會更加方便。
  • 數值會依輸入中的原樣寫法輸出。由於不會轉換為 JavaScript 數值,超過 2 的 53 次方(9,007,199,254,740,992)的 ID 以及 1.0 這樣的寫法在轉換前後都保持不變。

這些場景下會用到

把日誌交給分析工具

以一行一筆輸出的應用日誌,彙整成 JSON 陣列後,就能被以陣列為前提的工具與函式庫直接使用。

整理機器學習的訓練資料

訓練資料常以 JSONL 發布,而前處理指令碼卻期待陣列,本工具可作為兩者的橋梁。

匯入 BigQuery 或 Elasticsearch

兩者都接受換行分隔的 JSON 作為輸入格式,可將手邊的 JSON 陣列轉成可匯入的形式。

讓大型 JSON 能逐行處理

維持陣列就必須整份讀完才能開始處理;轉成 JSONL 後便能逐行依序處理。

JSON Lines 的相關術語

JSON Lines(JSONL)
每行寫一個 JSON 值的格式。整份檔案作為 JSON 並不合法(因為多個值並列)。優點在於每一行都能獨立讀取。
NDJSON
Newline Delimited JSON 的縮寫,與 JSON Lines 幾乎是同一件事。副檔名 .ndjson 即源自此稱呼。
串流處理
不先讀入整份資料,而是從抵達的開頭依序處理的方式。JSONL 適合這種方式,兩者因此經常搭配。
最外層
JSON 最外側的值。要轉為 JSONL 時此處必須是陣列 [...],若是物件 {...} 則無法轉換。
空行的處理
根據 JSON Lines 規範(jsonlines.org),空行不是有效的行。本工具採取寬鬆處理,會跳過空行再轉換,因此即使結尾有多餘的換行也能轉換。

常見問題

JSON 陣列會用 [ {...}, {...} ] 這樣的形式把整體包裹成一個數組,如果不解析整體就無法訪問單個元素。而 JSON Lines 是每行排列一個獨立的 JSON 物件,可以逐行進行流式處理,因此更適合對超大日誌檔案或機器學習資料集進行逐條處理。

常見於 OpenAI 及其他機器學習平臺的微調資料集、Elasticsearch、Logstash 等日誌採集工具的輸出格式,以及需要逐條獨立讀寫的大規模資料流式處理場景。

在"JSONL → JSON 陣列"模式下,每一行都必須是獨立有效的 JSON,哪怕只有一行存在語法錯誤,也會顯示包含該行號的錯誤資訊。在"JSON 陣列 → JSONL"模式下,整個輸入必須是陣列格式(以 [ 開頭、以 ] 結尾)。

轉換為 JSON 陣列的結果可以直接用 jq 命令或各程式語言的標準 JSON 解析器處理。反之,轉換為 JSONL 的結果與 jq -c、grep、awk 等按行處理的工具契合度很高,便於納入日誌分析流水線。
工具君

閒話 ― 為什麼會誕生"一行一條記錄"這種格式

JSON Lines(也稱 JSONL)這種格式誕生的背景,是因為普通的 JSON 陣列存在一個限制:在把整體讀入記憶體並解析完畢之前,無法取出哪怕一條中間資料。如果試圖用 JSON 陣列處理多達數百萬行的日誌資料或機器學習訓練資料集,就必須把整個檔案展開到記憶體中,對於超大檔案來說,這會帶來記憶體不足和解析耗時激增的問題。

JSON Lines 用"一行 = 一個完整的 JSON 物件"這樣簡單的約束解決了這個問題。由於可以一邊逐行讀取檔案一邊隨即解析,無需把整個檔案讀入記憶體,因此與流式處理、並行處理非常契合。這種設計理念也與 Unix 系統傳統的"一行一條記錄"文本處理文化(grep、awk、sed 等命令都按行工作)高度親和,可以直接嵌入現有的命令列工具鏈,這在實用層面也是很大的優勢。

如今它已被廣泛採用為 AI、機器學習領域的資料集分發格式,大語言模型的訓練資料以及用於微調的提示/回覆對,以 JSON Lines 格式分發的情況已相當普遍。