Convert a CSV file to JSON
Parse a CSV (with header row) and emit an array of JSON objects keyed by header.
How to convert a csv file to json in each shell
python3 -c "import csv, json, sys; print(json.dumps([dict(r) for r in csv.DictReader(sys.stdin)]))" < data.csvPython `csv.DictReader` parses RFC 4180 correctly (quoted-field-with-embedded-commas, escaped quotes `""` → `"`). One-line jq-only alternative for SIMPLE CSV (no quoted commas): `jq -Rsn '[inputs / "\n" | .[1:] | map(split(","))]'` — but it BREAKS on real-world CSV. For production scripts use Python or `mlr` (Miller).
python3 -c "import csv, json, sys; print(json.dumps(list(csv.DictReader(sys.stdin))))" < data.csvSame Python idiom. macOS ships Python 3 by default since 12. Note `csv.DictReader` returns ordered-dict items (insertion order matches CSV column order). For UTF-8 CSV with BOM: `csv.DictReader(open("f.csv", encoding="utf-8-sig"))` strips the BOM.
python3 -c "import csv, json, sys; print(json.dumps(list(csv.DictReader(sys.stdin))))" < data.csvSame Python. Fish-friendly capture: `set -l json (python3 -c "..." < data.csv)`. The `jq` one-liner alternative is fragile on quoted-comma CSVs — accept the Python dependency.
Import-Csv data.csv | ConvertTo-Jsonpwsh `Import-Csv` parses RFC 4180 natively — handles quoted-fields-with-commas, escaped quotes, line breaks inside quoted fields. The one-liner is true cross-platform on pwsh (Windows / Linux / macOS). `-Delimiter ";"` for semicolon-separated; `-Header "Col1","Col2"` if the CSV has no header row. Pipe to `ConvertTo-Json -Depth 10` for nested structures.
powershell -Command "Import-Csv data.csv | ConvertTo-Json"cmd has no native CSV/JSON support. Shell out to pwsh, which is built into Windows 10+. For a Python-only environment without pwsh: `python -c "..."` (same Python one-liner as bash) works in cmd too since Windows 10/11 has the Python launcher.
Equivalents listed for Bash, Zsh, Fish, PowerShell, cmd.exe.
Gotchas & notes
- **Quoted fields with embedded commas — the killer trap**: real-world CSVs have rows like `"Smith, John",30,NYC` where the first field contains a comma. Naive splitters (`awk -F,`, `cut -d,`, `column -t -s,`, jq `split(",")`) break this row into 4 fields instead of 3. RFC 4180 dictates that fields with commas / quotes / newlines are double-quoted, and literal quotes inside are doubled (`""`). Use a real CSV parser: pwsh `Import-Csv`, Python `csv` module, Miller `mlr`, `csvkit` (`csvjson data.csv`). Do NOT roll your own.
- **UTF-8 BOM**: CSV files exported from Excel often start with the bytes `0xEF 0xBB 0xBF` (UTF-8 BOM). Python `csv.DictReader` reads the BOM as part of the first header name — so `data["\ufeffName"]` instead of `data["Name"]`. Open with `encoding="utf-8-sig"` to strip. pwsh `Import-Csv` handles BOM automatically on pwsh 7+; pwsh 5.1 needs `Get-Content -Encoding UTF8 | ConvertFrom-Csv`.
- **Header row vs no-header**: `Import-Csv` (pwsh) assumes ROW 1 is headers. If the CSV has no headers, use `Import-Csv -Header "Col1","Col2","Col3"`. Python `csv.DictReader` similarly assumes row 1; for no-header CSVs use `csv.reader` (list-of-lists). jq has no header concept — must hand-roll.
- **Type coercion**: `Import-Csv` returns ALL columns as strings (`"30"`, not `30`). For typed JSON (numbers, booleans), post-process: `Import-Csv data.csv | ForEach-Object { $_.Age = [int]$_.Age; $_ } | ConvertTo-Json`. Python `csv.DictReader` is also string-only — cast in code. Miller `mlr` auto-detects types (`mlr --icsv --ojson cat data.csv`).
Related commands
Related tasks
- Parse JSON from a shell— Extract specific fields from a JSON blob (a curl response, kubectl output, log line) and pipe them into other shell tools — the everyday "grab the .token / .items[].name / .data.url" workflow that differs sharply from just pretty-printing.
- Format (pretty-print) JSON from a shell— Pretty-print a JSON blob from a curl response, log line, or config file — for human-readable inspection or diffing.