jq commands cheatsheet.
Filter, select, transform and aggregate JSON right in the terminal — the jq filters you reach for every day. Tap to copy.
jq '.'Pretty-print the input JSONjq -r '.name'Output a raw string without quotesjq '.foo.bar'Access a nested fieldjq '.foo?'Access a field without erroring if missingecho '{"a":1}' | jq '.a'Pipe JSON into jqjq '.[]'Iterate over array elementsjq '.[0]'Get the first element by indexjq '.[2:4]'Slice a range of elementsjq 'length'Count elements (or string length)jq 'map(.price)'Transform each element into a new arrayjq 'select(.age > 30)'Keep inputs matching a conditionjq '.items[] | select(.active)'Filter array elements by a fieldjq 'has("key")'Test whether an object has a keyjq 'map(select(.qty > 0))'Filter an array in placejq '.[] | select(.name == "Alice")'Match a field valuejq '{name, id}'Construct an object from fieldsjq '{n: .name}'Build an object with renamed keysjq '.name = "new"'Set a field valuejq 'to_entries'Convert an object to key/value pairsjq 'keys'List an object's keys, sortedjq '.a as $x | .b + $x'Bind a value to a variablejq 'add'Sum numbers (or concatenate arrays)jq 'group_by(.type)'Group array items by a fieldjq 'sort_by(.date)'Sort an array by a fieldjq 'unique'Remove duplicate valuesjq 'min'Smallest value in an arrayjq 'max'Largest value in an arrayjq -c '.'Compact output (one line)jq -s '.'Slurp all inputs into one arrayjq -n 'now'Run without input (null input)jq --arg name val '.x = $name'Pass a string variablejq -e '.active'Set the exit status from the outputcat file.json | jq '.'Pipe a file into jqWhat jq actually does
jq is a tiny command-line tool that treats JSON as a first-class data type, letting you slice, reshape and summarise it without writing a script. You hand it some JSON on standard input, give it a filter — a little expression describing what you want out — and it streams the result back. The simplest filter is ., the identity filter, which just pretty-prints whatever it reads, and almost everything else builds on that same dot-path idea.
Paths, pipes and raw output
You navigate into data with dot paths: .name pulls a field, .user.email reaches a nested one, and .[] spreads an array into a stream of its elements. Filters chain together with the pipe |, exactly like a shell pipeline, so .items[] | .price reads as "for each item, take its price". By default jq prints values as JSON, which means strings arrive wrapped in quotes; add -r when you want a bare string you can feed into another command.
Selecting and transforming
The select function is how you filter: .[] | select(.active) keeps only the elements that pass a test, and comparisons like select(.age > 30) work as you'd expect. To reshape data you build new objects with {} — {name, id} plucks two fields, while {n: .name} renames one — and map() applies a transform across a whole array. Helpers like keys, to_entries and has() round out most day-to-day object work.
Summaries and invocation flags
For aggregation, add sums an array, group_by and sort_by organise records by a field, and unique dedupes. A handful of flags change how jq runs: -c compacts each result onto one line, -s slurps multiple inputs into a single array, -n runs with null input, and --arg injects a shell value as a jq variable. jq pairs naturally with the curl commands for fetching an API response and the grep commands when you need plain-text search alongside it.