CSVからYAMLへの変換とは?
CSVからYAMLへの変換は、カンマ区切りの表形式データをYAML(YAML Ain't Markup Language)形式に変換する処理です。CSVファイルの各行がYAMLシーケンスの1エントリになり、各列ヘッダーがYAMLマッピングのキーに対応します。出力はインデントベースの人間可読なドキュメントで、設定ツールやデータパイプラインが追加のスキーマファイルなしに直接解析できます。
YAMLは2001年に初めて提案され、現在の仕様(YAML 1.2)は2009年に確定しました。KubernetesマニフェストのデフォルトフォーマットであるほかDocker ComposeファイルやAnsibleプレイブック、GitHub Actionsワークフロー、多くのCI/CDシステムで標準の設定フォーマットとして採用されています。ソースデータがスプレッドシートやデータベースエクスポートに存在する場合、CSVをYAMLに変換することが、設定エントリ・シードデータフィクスチャ・これらのシステム向けテスト入力を生成する最速の方法です。
正確なCSV to YAMLコンバーターは、RFC 4180の解析ルール(カンマや改行を含むクォートフィールド、エスケープされたダブルクォート、さまざまな区切り文字)を処理しなければなりません。YAML側では、真偽値に見える文字列(yes、no、true、false)や数値、nullはYAMLパーサーが意図しない型に変換するのを防ぐためクォートする必要があります。また、YAML 1.2がデフォルトエンコーディングとしてUTF-8を必須とするため、コンバーターはUnicodeコンテンツを扱い、有効なUTF-8出力を生成する必要があります。
CSV to YAMLコンバーターを使う理由
スプレッドシートデータから手作業でYAMLを書くのは面倒でミスが起きやすい作業です。インデントのずれやクォートされていない特殊文字が1つあるだけで無効なYAMLになり、設定のデプロイやデータインポートが壊れます。このコンバーターはCSVフィールドを解析し、ヘッダーをキーにマッピングして、適切なインデントと正しいクォートのYAML出力を生成します。
CSV to YAML変換のユースケース
CSV to YAMLマッピングリファレンス
CSVファイルの各構造要素はYAMLに対応する要素があります。
| CSVの概念 | YAMLの対応要素 | 詳細 |
|---|---|---|
| CSV file | YAML document | The entire file becomes a YAML sequence (array) of mappings |
| Header row | Mapping keys | Each column header becomes a key in every mapping entry |
| Data row | Sequence item (- ...) | Each row becomes one mapping item in the top-level array |
| Cell value | Scalar value | Strings, numbers, and booleans are inferred by YAML parsers |
| Empty cell | null or empty string | Rendered as null, ~, or an empty value depending on the tool |
| Comma delimiter | Indentation + colon | CSV delimiters are replaced by YAML key: value structure |
CSVとYAMLの比較
CSVは型情報や階層構造を持たないフラットな区切り文字フォーマットです。YAMLはインデントでネストを表現し、複数のデータ型をサポートし、コメントも書けるJSONのスーパーセットです。どちらを選ぶかはダウンストリームのツールが何を期待するかによります。
コード例
Node.js・Python・Go・CLIツールでの実践的なコード例です。いずれもCSVのヘッダー行をYAMLキーとして読み込み、各データ行をシーケンスのエントリにマッピングし、型の曖昧な値のクォートを適切に処理します。
import { parse } from 'csv-parse/sync'
import { stringify } from 'yaml'
const csv = `name,age,city
Alice,30,Berlin
Bob,25,"New York"`
const records = parse(csv, { columns: true, skip_empty_lines: true })
console.log(stringify(records))
// → - name: Alice
// → age: "30"
// → city: Berlin
// → - name: Bob
// → age: "25"
// → city: New York
// Vanilla JS (no dependencies)
function csvToYaml(csv) {
const [headerLine, ...dataLines] = csv.trim().split('\n')
const headers = headerLine.split(',')
return dataLines.map(line => {
const values = line.split(',')
return headers.map((h, i) => ` ${h}: ${values[i] || ''}`).join('\n')
}).map(block => `- ${block.trimStart()}`).join('\n')
}import csv, io, yaml
csv_string = """name,age,city
Alice,30,Berlin
Bob,25,New York"""
reader = csv.DictReader(io.StringIO(csv_string))
data = list(reader)
# default_flow_style=False produces block-style YAML
print(yaml.dump(data, default_flow_style=False, sort_keys=False))
# → - age: '30'
# → city: Berlin
# → name: Alice
# → - age: '25'
# → city: New York
# → name: Bob
# Preserve insertion order with sort_keys=False (Python 3.7+)
# To type-cast numbers: data = [{k: int(v) if v.isdigit() else v ...}]package main
import (
"encoding/csv"
"fmt"
"gopkg.in/yaml.v3"
"strings"
)
func main() {
input := "name,age,city
Alice,30,Berlin
Bob,25,New York"
r := csv.NewReader(strings.NewReader(input))
records, _ := r.ReadAll()
headers := records[0]
var data []map[string]string
for _, row := range records[1:] {
entry := make(map[string]string)
for i, h := range headers {
entry[h] = row[i]
}
data = append(data, entry)
}
out, _ := yaml.Marshal(data)
fmt.Println(string(out))
// → - age: "30"
// → city: Berlin
// → name: Alice
// → - age: "25"
// → city: New York
// → name: Bob
}# Using yq (https://github.com/mikefarah/yq) # yq reads CSV with --input-format=csv yq --input-format=csv --output-format=yaml '.' data.csv # Using Miller (mlr) — converts between CSV, JSON, YAML, and more mlr --icsv --oyaml cat data.csv # Python one-liner for quick conversion python3 -c " import csv, sys, yaml data = list(csv.DictReader(sys.stdin)) print(yaml.dump(data, default_flow_style=False, sort_keys=False)) " < data.csv