JSONL 教學:建立、讀取與轉換 JSONL 檔案
逐步教學,涵蓋使用 JSONL(JSON Lines)檔案所需了解的一切。包括 Python、JavaScript 和 CLI 工具的程式碼範例。
最後更新:2026 年 2 月
什麼是 JSONL?
JSONL(JSON Lines)是一種輕量級文字格式,其中每一行都是一個獨立的有效 JSON 值。與標準 JSON 將所有資料包裝在單一陣列或物件中不同,JSONL 將每行儲存一筆記錄,以換行符(\n)分隔。
這種逐行結構使 JSONL 非常適合串流處理大型資料集、附加記錄而無需重寫檔案,以及平行處理資料。它被 OpenAI 用於微調資料集、像 ELK stack 這樣的日誌系統,以及 BigQuery 和 Apache Spark 等大數據工具廣泛使用。
{"id":1,"name":"Alice","role":"engineer"}{"id":2,"name":"Bob","role":"designer"}{"id":3,"name":"Charlie","role":"manager"}
如何建立 JSONL 檔案
建立 JSONL 檔案很簡單:將每筆記錄序列化為單行 JSON 字串,然後寫入並加上換行符。以下是最流行語言的範例。
import jsonrecords = [{"id": 1, "name": "Alice", "role": "engineer"},{"id": 2, "name": "Bob", "role": "designer"},{"id": 3, "name": "Charlie", "role": "manager"},]with open("output.jsonl", "w", encoding="utf-8") as f:for record in records:f.write(json.dumps(record, ensure_ascii=False) + "\n")print("Created output.jsonl with", len(records), "records")
import { writeFileSync } from 'fs';const records = [{ id: 1, name: 'Alice', role: 'engineer' },{ id: 2, name: 'Bob', role: 'designer' },{ id: 3, name: 'Charlie', role: 'manager' },];const jsonl = records.map(record => JSON.stringify(record)).join('\n');writeFileSync('output.jsonl', jsonl + '\n', 'utf-8');console.log(`Created output.jsonl with ${records.length} records`);
手動 / 文字編輯器
您也可以在任何文字編輯器中建立 JSONL 檔案。只需每行輸入一個有效的 JSON 物件,行之間不加逗號,並將檔案儲存為 .jsonl 副檔名。確保每行都是完整且有效的 JSON。
如何讀取 JSONL 檔案
由於每一行都是一個獨立的 JSON 值,讀取 JSONL 檔案就像逐行迭代一樣簡單。以下是最常見的方法。
import jsonwith open("data.jsonl", "r", encoding="utf-8") as f:for line_number, line in enumerate(f, 1):line = line.strip()if not line:continue # skip empty linesrecord = json.loads(line)print(f"Line {line_number}: {record['name']} - {record['role']}")
import { createReadStream } from 'fs';import { createInterface } from 'readline';const rl = createInterface({input: createReadStream('data.jsonl', 'utf-8'),});let lineNumber = 0;for await (const line of rl) {if (!line.trim()) continue; // skip empty lineslineNumber++;const record = JSON.parse(line);console.log(`Line ${lineNumber}: ${record.name} - ${record.role}`);}
# 檢視前 10 行head -n 10 data.jsonl# 計算總記錄數wc -l data.jsonl# 使用 jq 美化列印每一行cat data.jsonl | jq .# 篩選 role 為 "engineer" 的記錄cat data.jsonl | jq 'select(.role == "engineer")'# 僅擷取 name 欄位cat data.jsonl | jq -r '.name'# 搜尋包含關鍵字的行grep '"Alice"' data.jsonl
如何將 JSON 轉換為 JSONL
如果您有標準 JSON 陣列,轉換為 JSONL 意味著將每個元素寫入為獨立的一行。這是最常見的 JSONL 操作之一。
import json# 讀取 JSON 陣列with open("data.json", "r", encoding="utf-8") as f:data = json.load(f) # expects a JSON array# 寫入為 JSONLwith open("data.jsonl", "w", encoding="utf-8") as f:for record in data:f.write(json.dumps(record, ensure_ascii=False) + "\n")print(f"Converted {len(data)} records from JSON to JSONL")
import { readFileSync, writeFileSync } from 'fs';// 讀取 JSON 陣列const data = JSON.parse(readFileSync('data.json', 'utf-8'));// 寫入為 JSONLconst jsonl = data.map(record => JSON.stringify(record)).join('\n');writeFileSync('data.jsonl', jsonl + '\n', 'utf-8');console.log(`Converted ${data.length} records from JSON to JSONL`);
如何將 CSV 轉換為 JSONL
將 CSV 轉換為 JSONL 會將每一列映射為一個 JSON 物件,使用 CSV 標頭作為欄位名稱。當將表格資料遷移到適合串流或機器學習的格式時,這很有用。
import csvimport jsonwith open("data.csv", "r", encoding="utf-8") as csv_file:reader = csv.DictReader(csv_file)with open("data.jsonl", "w", encoding="utf-8") as jsonl_file:for row in reader:jsonl_file.write(json.dumps(row, ensure_ascii=False) + "\n")print("Converted CSV to JSONL successfully")
import { readFileSync, writeFileSync } from 'fs';const csv = readFileSync('data.csv', 'utf-8');const lines = csv.trim().split('\n');const headers = lines[0].split(',');const jsonl = lines.slice(1).map(line => {const values = line.split(',');const obj = {'};headers.forEach((h, i) => obj[h.trim()] = values[i]?.trim());return JSON.stringify(obj);}).join('\n');writeFileSync('data.jsonl', jsonl + '\n', 'utf-8');console.log('Converted CSV to JSONL successfully');
JSONL 最佳實踐
對所有 JSONL 檔案使用 UTF-8 編碼。這確保跨平台相容性並支援國際字元。
每行恰好寫入一個 JSON 物件。永遠不要將 JSON 物件拆分為多行,也不要在同一行上放置多個物件。
不要在行之間添加逗號。與 JSON 陣列不同,JSONL 使用換行符作為唯一的分隔符。
獨立驗證每一行。每一行必須是完整、有效的 JSON 值。使用 JSONL 驗證器及早發現語法錯誤。
對大型檔案使用串流讀取。不要將整個檔案載入記憶體,而是使用 readline(Node.js)或檔案迭代(Python)逐行處理。
保持記錄結構一致。雖然 JSONL 允許每行有不同的架構,但保持統一的結構使資料處理更容易。
避免尾隨空白。確保行末沒有多餘的空格或 Tab,這可能導致解析問題。
檔案以換行符結尾。最後一筆記錄之後的尾隨換行符幫助像 wc 和 cat 這樣的工具正確處理檔案。
常見的 JSONL 錯誤
[
{"name":"Alice"},
{"name":"Bob"}
]{"name":"Alice"}
{"name":"Bob"}JSONL 不是 JSON 陣列。不要用方括號包裝行或在它們之間添加逗號。每一行都是獨立的。
{"name":"Alice"},
{"name":"Bob"},{"name":"Alice"}
{"name":"Bob"}每行之後的尾隨逗號或行之間的逗號在 JSONL 中無效。換行符是唯一的分隔符。
{
"name": "Alice",
"age": 30
}{"name":"Alice","age":30}每個 JSON 物件必須在單一行上。帶有縮排和換行符的美化列印 JSON 不是有效的 JSONL。
{"text":"She said "hello""}{"text":"She said \"hello\""}JSON 字串內的引號和特殊字元必須使用反斜線正確跳脫。未跳脫的引號會破壞 JSON 解析器。