I have an array and I need to check if elements exists in that array or to get that element from the array using jq, fruit.json:
{
"fruit": [
"apple",
"orange",
"pomegranate",
"apricot",
"mango"
]
}
cat fruit.json | jq '.fruit .apple'
does not work
The semantics of 'contains' is not straightforward at all. In general, it would be better to use 'index' to test if an array has a specific value, e.g.
.fruit | index( "orange" )
IN/1
If your jq has IN/1
then a better solution is to use it:
.fruit as $f | "orange" | IN($f[])
If your jq has first/1
(as does jq 1.5), then here is a fast definition of IN/1
to use:
def IN(s): first((s == .) // empty) // false;
To have jq
return success if the array fruit
contains "apple"
, and error otherwise:
jq -e '.fruit[]|select(. == "apple")' fruit.json >/dev/null
To output the element found, omit >/dev/null
.
[WARNING: SEE THE COMMENTS AND ALTERNATIVE ANSWERS.]
cat fruit.json | jq '.fruit | contains(["orange"])'
For future visitors, if you happen to have the array in a variable and want to check the input against it, and you have jq 1.5 (without IN), your best option is index
but with a second variable:
.inputField as $inputValue | $storedArray|index($inputValue)
This is functionally equivalent to .inputField | IN($storedArray[])
.
If you're open to using something other than jq
, then I can highly recommend Xidel.
With it you can combine JSONiq and XPath/XQuery to process JSON!
To have it simply return a boolean:
$ xidel -s fruit.json -e '$json/contains((fruit)(),"apple")'
true
To have it return the element if the array fruit
contains "apple":
$ xidel -s fruit.json -e '$json/(fruit)()[contains(.,"apple")]'
apple
Above is "XPath notation". "Dot notation" (like jq
):
$ xidel -s fruit.json -e '($json).fruit()[contains(.,"apple")]'
apple
Also, there's been developed another alternative JSON manipulation unix tool now, offering a novel approach to handle JSONs - walk-path
unix utility jtc
.
Here are some examples how to achieve the ask:
1. When entry exists - it'll be printed, otherwise a blank returned:
bash $ <fruit.json jtc -w'<mango>'
"mango"
bash $ <fruit.json jtc -w'<mangos>'
bash $
2. When entry exists print true
, otherwise print false
:
bash $ <fruit.json jtc -w'<res:false>f<mango><res:true>v' -T'{{res}}'
true
bash $ <fruit.json jtc -w'<res:false>f<mangos><res:true>v' -T'{{res}}'
false
bash $
3. When entry is present print it, otherwise print "FALSE"
:
bash $ <fruit.json jtc -w'<r:"FALSE">f<mango><r>v' -T'{{r}}'
"mango"
bash $ <fruit.json jtc -w'<r:"FALSE">f<mangos><r>v' -T'{{r}}'
"FALSE"
bash $
PS> Disclosure: I'm the creator of the jtc
- shell cli tool for JSON operations
来源:https://stackoverflow.com/questions/43259563/how-to-check-if-element-exists-in-array-with-jq