I have a file with lines like this:
{"items":["blue","green"]} {"items":["yellow","green"]} {"items":["blue","pink"]}
How can I use jq to select and show only the JSON values that have "blue" in their "items" array?
So the output would be:
{"items":["blue","green"]} {"items":["blue","pink"]}
A jq program is a "filter": it takes an input, and produces an output. There are a lot of builtin filters for extracting a particular field of an object, or converting a number to a string, or various other standard tasks.
Identity: . (dot) in jq represent the entire input without any filters. JQ command followed by a dot will output the input as it is with some formatting to make it pretty. You can use jq . command to format the output of a curl command.
JSONPath distinguishes between the "root object or element" ($) and "the current object or element" (.). jq simply uses . to refer to the current JSON entity and so it is context-dependent: it can refer to items in the input stream of the jq process as a whole, or to the output of a filter.
Found out the answer
jq 'select(.items | index("blue"))'
On Jan 30, 2017, a builtin named IN
was added for efficiently testing whether a JSON entity is contained in a stream. It can also be used for efficiently testing membership in an array. In the present case, the relevant usage would be:
select( .items as $items | "blue" | IN($items[]) )
If your jq does not have IN/1
, then so long as your jq has first/1
, you can use this equivalent definition:
def IN(s): . as $in | first(if (s == $in) then true else empty end) // false;
Using any/0
here is relatively inefficient, e.g. compared to using any/1
:
select( any( .items[]; . == "blue" ))
(In practice, index/1
is usually fast enough, but its implementation currently (jq 1.5 and versions through at least July 2017) is suboptimal.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With