Check whether any value is zero using jq and return 0 to the calling shell script

9,708

any is a built-in filter that returns true if any item is true, and false otherwise. --exit-status/-e causes jq to exit 0 iff the last output is neither false nor null.

If you've already winnowed the document down to just the keys you care about like in your script, you can just do this:

previous_command | jq -e 'any( .[] ; . == 0 )'

.[] pulls all the values out, and any will output true only if it finds a zero in them. Alternatively, [.[]|.==0]|any or map(.==0) | any; pick whichever one you find clearest.


You can also do the whole thing in one go, saving a wasted jq process:

jq -e '[to_entries | .[] | select(.key | test("key[0-9][0-9]$")) | .value == 0 ] | any' data.json

This selects all the matching keys and checks whether each value is 0, then pipes the collection of results through any, thus exiting 0 if there were any zeros. If you're sure there are no NaNs you could also multiply them all together with reduce.

Share:
9,708

Related videos on Youtube

pyramid13
Author by

pyramid13

Updated on September 18, 2022

Comments

  • pyramid13
    pyramid13 over 1 year

    I have this JSON file:

    { "key11":1010, "key12":12120, "key13":12103 }

    How can I use jq to check whether any of the values corresponding to a key[0-9][0-9] are zero, making jq exit successfully if any is and not otherwise?

    I have this script from a previous question

    #!/bin/bash
    json=$(cat <<EOF
    {"key11":12120,"key11_":13,"key11_yes":12107,
    "key12":13492,"key12_no":9,"key12_yes":13483,
    "key13":10200,"key13_no":9,"key13_yes":10191,
    "key21":16756,"key21_no":30,"key21_yes":16726,
    "key22":17057,"key22_no":34,"key22_yes":17023,
    "key23":16798,"key23_no":25,"key23_yes":16773,
    "key31":2733,"key31_yes":2733,
    "key32":2561,"key32_yes":2561,
    "key33":2570,"key33_yes":2570}
    EOF
    )
    json2=$(echo ${json}|jq 'with_entries(if (.key|test("key[0-9][0-9]$")) then ( {key: .key, value: .value } ) else empty end )')
    

    The result is:

    { "key11": 12120, "key12": 13492, "key13": 10200, "key21": 16756, "key22": 17057, "key23": 16798, "key31": 2733, "key32": 2561, "key33": 2570 }
    

    Now I want check the value attached to all keys in $json2, and then if the value of any of the entries is zero return 0.

  • pyramid13
    pyramid13 about 6 years
    If we want to look at the exact format of a keys, what should we do? i use json2=$(echo ${json}|jq -e '[to_entries | .[] | (.key | test("key[0-9][0-9]$"))] | any ') but return true even if we have only key.
  • Angel Todorov
    Angel Todorov about 6 years
    @pyramid13, important to quote the variable: echo "$json" not echo ${json}. To illustrate, set json="foo * bar" and try the 2 echo commands.
  • pyramid13
    pyramid13 almost 6 years
    @Michael Homer, please look my qustion