jq for JSON Processing from the Terminal
August 27, 2026 · RividTech
APIs, config files, and CLI tools all speak JSON. Once the payload is on your machine, you often need a slice of it: one field, a filtered list, or a flatter shape for a spreadsheet. jq is the standard tool for that job in the terminal — fast, scriptable, and available on almost every developer machine.
This guide covers the filters you will reach for daily, how to pipe jq into the rest of your shell workflow, and when a private browser tool is a better fit than writing a one-liner.
What jq is
jq is a lightweight command-line JSON processor. You pass it JSON on stdin (or a file), give it a filter expression, and it prints the result. Filters can select fields, walk arrays, rewrite objects, and format output — all without writing a Python or Node script.
Think of it as sed / awk for structured data: small expressions, big leverage in pipelines.
Install
On macOS with Homebrew:
brew install jqOn Debian/Ubuntu:
sudo apt install jqConfirm with jq --version. Windows users can install via winget, Chocolatey, or download a binary from the official jq releases.
Identity and pretty-print
The simplest useful filter is . — the identity. It pretty- prints JSON, which is already enough for many API responses:
curl -s https://api.example.com/user | jq .
cat data.json | jq .
jq . data.jsonCompact (one-line) output uses -c:
jq -c . data.jsonFor a quick format-only pass in the browser — no install required — use JSON Formatter.
Select fields
Dot paths pull nested values:
jq '.name' user.json
jq '.address.city' user.json
jq '.user.profile.email' response.jsonBuild a smaller object with the object constructor. Keys on the left are output names; values on the right are paths into the input:
jq '{name: .name, city: .address.city}' user.jsonMissing paths become null. Use the optional operator ? when a key might not exist:
jq '.address?.city' user.jsonWork with arrays
.[] streams each element. Combine with a path to project a field from every item:
jq '.[].id' users.json
jq '.items[].sku' order.json
jq '.[] | {id, name}' users.jsonIndex and slice like most languages:
jq '.[0]' users.json
jq '.[-1]' users.json
jq '.[0:3]' users.jsonlength, keys, and type are handy for inspection:
jq 'length' users.json
jq 'keys' user.json
jq 'map(type)' mixed.jsonFilter rows
select keeps values that match a condition. Pipe array elements into it:
jq '.[] | select(.active == true)' users.json
jq '.[] | select(.price > 100)' products.json
jq '.[] | select(.role == "admin")' users.json
jq '[.[] | select(.status == "open")]' tickets.jsonThe last form wraps results back into an array (useful when the next step expects a JSON array, not a stream of objects).
String matching uses contains, startswith, or test (regex):
jq '.[] | select(.email | endswith("@example.com"))' users.json
jq '.[] | select(.name | test("(?i)acme"))' orgs.jsonMap and reshape
map transforms every element of an array:
jq 'map({id, name})' users.json
jq 'map(.price * 1.1)' products.json
jq 'map(.tags[])' posts.jsonNested objects often need flattening before CSV or Excel. In jq you can pull nested paths into top-level keys:
jq 'map({
id,
name,
city: .address.city,
zip: .address.zip
})' users.jsonPrefer a visual flatten when you are exploring unfamiliar payloads: Flatten JSON, then export with JSON to CSV. For the full flatten story, see Flatten Nested JSON for Spreadsheets and CSV.
Export CSV from the terminal
jq can emit CSV with @csv. Headers are manual — build a header row, then map data rows:
jq -r '
(["id","name","city"]),
(.[] | [.id, .name, .address.city])
| @csv
' users.json-r (raw output) drops JSON string quotes so the result is plain CSV. For one-off exports without shell scripting, JSON to CSV or JSON to Excel may be faster.
Useful flags
-r— raw strings (no quotes); needed for CSV and plain text.-c— compact, one object per line.-s— slurp: read the whole input stream into one array.-n— null input; build JSON from the filter alone.--arg name value— pass a shell string into the filter as$name.
jq --arg city "Berlin" \
'[.[] | select(.address.city == $city)]' users.jsonRecipes worth memorizing
# Sort objects by a field
jq 'sort_by(.created_at)' events.json
# Unique values of a field
jq '[.[].status] | unique' tickets.json
# Group by key
jq 'group_by(.role) | map({role: .[0].role, count: length})' users.json
# Merge two objects (right wins)
jq -s '.[0] * .[1]' a.json b.json
# Delete a key
jq 'del(.password)' user.json
# Default when null
jq '.nickname // .name' user.jsonPipelines with curl and files
jq shines in shell pipelines. Fetch, filter, and write in one line:
curl -s https://api.example.com/users \
| jq '[.[] | select(.active) | {id, email}]' \
> active-users.jsonProcess many files with a loop, or use jq -s when you need all inputs as one array. Keep secrets out of shell history — prefer files or env vars over pasting tokens on the command line.
When browser tools are enough
jq is ideal for automation, CI, and large or repetitive jobs. For a one-time look at a payload, or when you want a table without writing a filter, browser-only tools are often simpler:
- JSON Formatter — pretty-print and validate.
- JSON Preview — inspect structure visually.
- Flatten JSON — nested objects → flatter shape.
- JSON to CSV / JSON to Excel — spreadsheet export without
@csvboilerplate.
RividTech runs those steps entirely in your browser — nothing is uploaded. That matters for API dumps with personal data or tokens; see Why Browser-Only CSV Tools Are Safer for Your Data.
Getting started
Install jq, pretty-print a sample file with jq ., then try selecting one field and filtering an array. When you need a table for someone who will not run shell commands, pipe the result into a file and convert with JSON to CSV, or skip the CLI and start from JSON Formatter in the browser.