JSONL 튜토리얼: JSONL 파일 생성, 읽기 및 변환
JSONL(JSON Lines) 파일 작업에 대해 알아야 할 모든 것을 다루는 단계별 튜토리얼입니다. Python, JavaScript 및 CLI 도구의 코드 예제를 포함합니다.
최종 업데이트: 2026년 2월
JSONL이란?
JSONL(JSON Lines)은 각 줄이 별도의 유효한 JSON 값인 경량 텍스트 형식입니다. 모든 데이터를 단일 배열이나 객체로 래핑하는 표준 JSON과 달리, JSONL은 줄바꿈 문자(\n)로 구분된 줄당 하나의 레코드를 저장합니다.
이 줄 단위 구조는 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 파일을 만들 수 있습니다. 줄 사이에 쉼표 없이 줄당 하나의 유효한 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 # 빈 줄 건너뛰기record = 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; // 빈 줄 건너뛰기lineNumber++;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) # JSON 배열 예상# 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 인코딩을 사용하세요. 이렇게 하면 플랫폼 간 호환성이 보장되고 국제 문자를 지원합니다.
줄당 정확히 하나의 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 객체는 한 줄에 맞아야 합니다. 들여쓰기와 줄 바꿈이 있는 보기 좋게 출력된 JSON은 유효한 JSONL이 아닙니다.
{"text":"She said "hello""}{"text":"She said \"hello\""}JSON 문자열 내의 따옴표와 특수 문자는 백슬래시로 적절하게 이스케이프되어야 합니다. 이스케이프되지 않은 따옴표는 JSON 파서를 중단시킵니다.