How to check if element exists in array with jq

一世执手 提交于 2019-11-27 14:39:43

问题


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


回答1:


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;



回答2:


[WARNING: SEE THE COMMENTS AND ALTERNATIVE ANSWERS.]

cat fruit.json | jq '.fruit | contains(["orange"])'



回答3:


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(s) found, omit >/dev/null. If searching for a fixed string, this isn't very relevant, but it might be if the select expression might match different values, e.g. if it's a regexp.

To output only distinct values, pass the results to unique.

jq '[.fruit[]|select(match("^app"))]|unique' fruit.json

will search for all fruits starting with app, and output unique values. (Note that the original expression had to be wrapped in [] in order to be passed to unique.)




回答4:


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[]).




回答5:


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



回答6:


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'<apple>'
"apple"
bash $ <fruit.json jtc -w'<plum>'
bash $ 

2. When entry exists print true, otherwise print false:

bash $ <fruit.json jtc -w'<res:false>f<apple><res:true>v' -T'{{res}}'
true
bash $ <fruit.json jtc -w'<res:false>f<plum><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<apple><r>v' -T'{{r}}'
"apple"
bash $ <fruit.json jtc -w'<r:"FALSE">f<plum><r>v' -T'{{r}}'
"FALSE"
bash $ 

PS. Disclosure: I'm the creator of the jtc - shell cli tool for JSON operations PSS. disclosure of affiliation with the product is required by SO.



来源:https://stackoverflow.com/questions/43259563/how-to-check-if-element-exists-in-array-with-jq

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!