0

I'm trying to detect when I get all empty json values.

Here are 2 examples of empty json values.

json='{
  "data": [],
  "pagination": {
    "cursor": ""
  }
}'

json='{
    "data": [],
    "error": "",
    "message": "",
    "status": ""
}'

The closest I've gotten is this, which seems to work for the first example, but not the 2nd.

echo "$json" | jq -e 'all( .[] ; . == "" or . == [] or . == {}  )'

One, I thought easy way, would be to get the string text from each key pair, then just check if I'm left with an empty string. But I haven't found a way that works in the pagination example.

Mint
  • 14,388
  • 30
  • 76
  • 108
  • Check out https://stackoverflow.com/questions/7340060/javascript-or-jquery-looping-a-multidimensional-object – GoinOff Sep 27 '22 at 14:36
  • That is a possibility, but I was hoping there was a more compact solution. – Mint Sep 27 '22 at 14:44

2 Answers2

1

This will give you false if all strings and arrays are "" or []:

jq -e 'all(.. | strings, arrays; IN("", [])) | not'

Demo

pmf
  • 24,478
  • 2
  • 22
  • 31
  • This is exactly what I was after! Thank you so much. – Mint Sep 27 '22 at 14:51
  • 1
    Note: Applying [De Morgan's laws](https://en.wikipedia.org/wiki/De_Morgan%27s_laws), the filter can also be expressed using `any` by bringing `not` inside to act on `IN`: `any(.. | strings, arrays; IN("", []) | not)` – pmf Sep 27 '22 at 16:11
1

This might be a good use for gron

json='{
  "data": [],
  "pagination": {
    "cursor": "",
    "position":[2,3]
  }
}'

gron transforms the input JSON into discrete paths:

$ gron <<< "$json"
json = {};
json.data = [];
json.pagination = {};
json.pagination.cursor = "";
json.pagination.position = [];
json.pagination.position[0] = 2;
json.pagination.position[1] = 3;

and to test for any non-empty elements

$ gron <<< "$json" | grep -Evq '(\{\}|\[\]|"");$' && echo "not everything is empty"
not everything is empty
glenn jackman
  • 238,783
  • 38
  • 220
  • 352