How to filter and query JSON with jq
Updated 2026-06-21
To filter JSON with jq, you write a small expression that says which parts of the document you want — start with a dot to mean "the whole input", add a key name to drill into an object, and use brackets to walk arrays. Paste your JSON, type a filter, and read the result. The fastest way to learn is to run filters against your own data and watch the output change live.
The core filters
A jq filter is a pipeline: the JSON flows in on the left, each step transforms it, and the result comes out the right. These few building blocks cover most day-to-day work:
- Identity — a single dot returns the input unchanged. Handy as a pretty-printer for messy JSON.
- Object access — .name pulls the value of the name key. Chain them: .user.email reaches a nested field.
- Array index — .items[0] grabs the first element; .items[-1] grabs the last.
- Array iteration — .items[] emits every element in turn, so the rest of your filter runs once per item.
- The pipe — feed one filter's output into the next, for example .users[] | .name to list every user's name.
A worked example
Say you have an object with a users array, each user having name, age and active fields. To get the names of only the active users, you iterate the array, keep the ones that match, then project the field:
.users[] | select(.active) | .name
The select function keeps only inputs where the condition is true, dropping the rest. To reshape results instead of filtering them, wrap your expression in braces to build a new object — for example { person: .name, years: .age } renames keys on the fly. To collect streamed results back into a single array, wrap the whole thing in square brackets.
Common pitfalls
- Forgetting the leading dot. Just name is invalid; jq needs .name to know you mean a key of the current input.
- Confusing .items[] with .items. The first streams each element; the second returns the array as one value. Add [] when you want to act on items individually.
- Quoting keys with special characters. A key with a dash or space needs quotes and brackets, like .["first-name"], not .first-name.
- Strings vs numbers. Comparisons are type-aware, so .age > "30" will not behave like .age > 30.
Try it in your browser
The jq & JSONPath Playground runs jq filters over your JSON live as you type, so you get instant feedback while you learn — no install, no command line. Because everything executes in your browser, your JSON never leaves your machine and nothing is uploaded, which matters when the data is a config dump or an API response with private fields.
Paste your JSON, start with a single dot, and build up your filter one step at a time in the jq & JSONPath Playground.