0

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.

  • 1
    What does "value keys are zero" mean? – Michael Homer May 19 '18 at 6:46
  • You seem to have an existing script, could you please share it with us so that we can see what you're trying to do? – Kusalananda May 19 '18 at 6:47
  • e.g : { "key11":1010, "key12":12120, "key13":12103, "key14": 0 } If the value of each of the keys is zero, script return 0 status. – pyramid13 May 19 '18 at 6:49
  • @pyramid13, elaborate your condition: it should return 0 if ANY of keys is 0? – RomanPerekhrest May 19 '18 at 6:59
  • @Kusalananda, The script was shared :) – pyramid13 May 19 '18 at 7:01
3

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.

  • 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. – pyramid13 May 19 '18 at 8:55
  • @pyramid13, important to quote the variable: echo "$json" not echo ${json}. To illustrate, set json="foo * bar" and try the 2 echo commands. – glenn jackman May 19 '18 at 12:56
  • @Michael Homer, please look my qustion – pyramid13 May 21 '18 at 7:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.