Almost every API returns lists, and .[] is how you process each item.
Arrays are indexed from zero: .[0] is the first element, .[-1] the last. Slices .[2:4] return a sub-array (start inclusive, end exclusive); .[:3] takes the first three. Out-of-range indexes return null.
The iterator .[] is the key idea of jq. It does not output an array; it outputs each element separately, as a stream of results. Following filters then run once per element:
jq '.[].name' prints the name of every object in a top-level array, one per line.
.[] works on objects too, producing each value. Combined with field access you can dig through nested lists: .orders[].items[].sku.
Because each element becomes a separate output, wrap the expression in brackets to collect results back into an array: [.[].name] gives ["Ann","Bob"]. That pair, iterate then collect, is the basis of most transformations.
length gives the number of elements of an array, keys of an object, or characters of a string. .[]? iterates without error if the input might not be iterable.
Many JSON tools output newline-delimited JSON (one object per line). jq handles that natively: it runs the filter once for each input value.
Example
echo '[{"name":"Ann","tags":["a","b"]},{"name":"Bob","tags":["c"]}]' > p.json
jq '.[0].name' p.json # "Ann"
jq '.[-1].name' p.json # "Bob"
jq -r '.[].name' p.json # Ann
# Bob
jq -c '[.[].name]' p.json # ["Ann","Bob"]
jq -c '.[].tags[]' p.json # "a" "b" "c" (three outputs)
jq 'length' p.json # 2
jq -c '.[0].tags[:1]' p.json # ["a"]Remember
- .[0], .[-1], .[a:b] index and slice
- .[] outputs each element as a separate result
- Wrap in [ ... ] to collect results back into an array
Watch out for
- Expecting .[] to return an array; it produces a stream, so wrap it in [] when you need a list.