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 jq
On Debian/Ubuntu:
sudo apt install jq
Confirm 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.json
Compact (one-line) output uses -c:
jq -c . data.json
For 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.json
Build 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.json
Missing paths become null. Use the optional operator ? when a key might not exist:
jq '.address?.city' user.json
Work 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.json
Index and slice like most languages:
jq '.[0]' users.json
jq '.[-1]' users.json
jq '.[0:3]' users.json
length, keys, and type are handy for inspection:
jq 'length' users.json
jq 'keys' user.json
jq 'map(type)' mixed.json
Filter 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.json
The 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.json
Map 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.json
Nested 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.json
Prefer 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.json
Recipes 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.json
Pipelines 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.json
Process 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.