Comment by nothrabannosir
Comment by nothrabannosir 6 days ago
crucial jq insight which unlocked the tool for me: it's jsonl, not json.
it's a pipeline operating on a stream of independent json terms. The filter is reapplied to every element from the stream. Streams != lists; the latter are just a data type. `.` always points at the current element of the stream. Functions like `select` operate on separate items of the stream, while `map` operates on individual elements of a list. If you want a `map` over all elements of the stream: that's just what jq is, naturally :)
stream of a single element which is a list:
echo '[1,2,3,4]' | jq .
# [1,2,3,4]
unpack the list into a stream of separate elements: echo '[1,2,3,4]' | jq '.[]'
# 1
# 2
# 3
# 4
echo '[1,2,3,4]' | jq '.[] | .' # same: piping into `.` is a NOP:
only keep elements 2 and 4 from the stream, not from the array--there is no array left after .[] : echo '[1,2,3,4]' | jq '.[] | select(. % 2 == 0)'
# 2
# 4
keep the array: echo '[1,2,3,4]' | jq 'map(. * 2)'
# [2,4,6,8]
map over individual elements of a stream instead: echo '[1,2,3,4]' | jq '.[] | . * 2'
# 2
# 4
# 6
# 8
printf '1\n2\n3\n4\n' | jq '. * 2' # same
This is how you can do things like printf '{"a":{"b":1}}\n{"a":{"b":2}}\n{"a":{"b":3}}\n' | jq 'select(.a.b % 2 == 0) | .a'
# {"b": 2}
select creates a nested "scope" for the current element in its parens, but restores the outer scope when it exits.Hope this helps someone else!