How to check if element exists in array with jq

前端 未结 5 800
悲哀的现实
悲哀的现实 2020-12-08 14:53

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:

{
    \"fr         


        
相关标签:
5条回答
  • 2020-12-08 14:54

    [WARNING: SEE THE COMMENTS AND ALTERNATIVE ANSWERS.]

    cat fruit.json | jq '.fruit | contains(["orange"])'
    
    0 讨论(0)
  • 2020-12-08 14:54

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

    0 讨论(0)
  • 2020-12-08 14:55

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

    0 讨论(0)
  • 2020-12-08 14:58

    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
    
    0 讨论(0)
  • 2020-12-08 15:06

    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;
    
    0 讨论(0)
提交回复
热议问题