JSONL チュートリアル:JSONL ファイルの作成・読み込み・変換
JSONL(JSON Lines)ファイルの扱い方について知っておくべきすべてをカバーするステップバイステップチュートリアル。Python、JavaScript、CLI ツールのコード例を含みます。
最終更新: 2026年2月
JSONL とは?
JSONL(JSON Lines)は、各行が個別の有効な JSON 値である軽量なテキスト形式です。すべてのデータを単一の配列またはオブジェクトにラップする標準 JSON とは異なり、JSONL は改行文字(\n)で区切られた 1 行に 1 つのレコードを保存します。
この行単位構造により、JSONL は大規模データセットのストリーミング、ファイル全体を書き直さずにレコードを追加すること、並列データ処理に最適です。OpenAI のファインチューニングデータセット、ELK スタックなどのロギングシステム、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 ファイルを作成できます。行間にカンマを入れずに、1 行に 1 つの有効な 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 操作の 1 つです。
import json# JSON 配列を読み込むwith open("data.json", "r", encoding="utf-8") as f:data = json.load(f) # expects a JSON array# JSONL として書き出すwith 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'));// JSONL として書き出すconst 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 エンコーディングを使用します。これにより、プラットフォーム間の互換性が確保され、国際文字がサポートされます。
1 行に正確に 1 つの JSON オブジェクトを書きます。JSON オブジェクトを複数行に分割したり、同じ行に複数のオブジェクトを配置したりしないでください。
行間にカンマを追加しないでください。JSON 配列とは異なり、JSONL は改行文字を唯一の区切り文字として使用します。
各行を独立して検証します。すべての行が完全で有効な JSON 値でなければなりません。構文エラーを早期に捉えるために JSONL バリデーターを使用してください。
大きなファイルにはストリーミング読み込みを使用します。ファイル全体をメモリに読み込むのではなく、readline(Node.js)またはファイル反復(Python)を使用して行単位で処理します。
レコードの構造を一貫させます。JSONL は行ごとに異なるスキーマを許可しますが、統一された構造を維持することでデータ処理がはるかに簡単になります。
末尾の空白を避けます。行に余分なスペースやタブがあると、解析の問題を引き起こす可能性があるため、行にそれらがないことを確認してください。
ファイルを改行で終了します。最後のレコードの後に末尾の改行があると、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 オブジェクトは 1 行に収まる必要があります。インデントと改行を含む整形された JSON は有効な JSONL ではありません。
{"text":"She said "hello""}{"text":"She said \"hello\""}JSON 文字列内の引用符や特殊文字は、バックスラッシュで適切にエスケープする必要があります。エスケープされていない引用符は JSON パーサーを壊します。