bendem
bendem

Reputation: 365

Merge multiple jq invocations to sort and limit the content of a stream of objects

I have a json stream of updates for products, and I'm trying to get the last X versions sorted by version (they are sorted by release date currently).

It looks like jq can't sort a stream of objects directly, sort_by only works on arrays, and I couldn't find a way to collect a stream into an array that doesn't involve piping the output of jq -c to jq -s.

My current solution:

< xx \
    jq -c '.[] | select(.platform | contains("Unix"))' \
    | jq -cs 'sort_by(.version) | reverse | .[]' \
    | head -5 \
    | jq -C . \
    | less

I expected to be able to use

jq '.[] | select(...) | sort_by(.version) | limit(5) | reverse'

but I couldn't find a thing that limits and sort_by doesn't work on non arrays.

I am testing this on atlassian's json for releases: https://my.atlassian.com/download/feeds/archived/bamboo.json

Upvotes: 1

Views: 590

Answers (1)

Inian
Inian

Reputation: 85790

In jq you can always contain the results to an array using the [..] that put the results to an array for the subsequent functions to operate on. Your given requirement could be simply done as

jq '[.[] | select(.platform | contains("Unix"))] | sort_by(.version) | limit(5;.[])'

See it working on jq playground tested on v1.6

and with added reverse() function, introduce an another level of array nesting. Use reverse[] to dump the objects alone

jq '[[.[] | select(.platform | contains("Unix"))] | sort_by(.version) | limit(5;.[]) ] | reverse'

Upvotes: 1

Related Questions