Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use JQ "contains" and suppress errors when key not found

I am trying to get the value based on the "contains" value of another key in the same object

I have already tried a code and it works and outputs the result that I want, but some objects in the JSON do not have this key as such I get:

jq: error (at <stdin>:1): null (null) and string ("BBC") cannot have their containment checked

or the reason for this error are the arrays in other keys, I am not sure

Using:

jq '.entries[] | select(.icon | contains("BBC")) | .uuid'

I want the UUID of the found result with no errors and store it as a variable in shell

"174501xxxxxxxxxxxxxe6342a03"

Input file that is piped

{  
   "entries":[  
      {  
         "uuid":"174501xxxxxxxxxxxxxe6342a03",
         "enabled":true,
         "autoname":true,
         "name":"BBC",
         "number":0,
         "icon":"file:///logos/BBC.png",
         "icon_public_url":"imagecache/1097",
         "epgauto":true,
         "epggrab":[  ],
         "dvr_pre_time":0,
         "dvr_pst_time":0,
         "epg_running":-1,
         "services":[  ],
         "tags":[  ],
         "bouquet":""
      },
      {  
         "uuid":"174501xxxxxxxxxxxxxe6342a04",
         "enabled":true,
         "autoname":true,
         "name":"ABC",
         "number":0,
         "icon_public_url":"imagecache/1098",
         "epgauto":true,
         "epggrab":[  ],
         "dvr_pre_time":0,
         "dvr_pst_time":0,
         "epg_running":-1,
         "services":[  ],
         "tags":[  ],
         "bouquet":""
      }...
like image 608
mfaiz Avatar asked Jan 08 '19 08:01

mfaiz


2 Answers

There is more than one way to achieve this with jq. You could use conditionals and branching but I think the simplest way is using try-catch without the catch to just silence any error. The documentation is at the end of Conditionals and Comparisons

Here is an example that will simply omit the error and only print the UUIDs if there is no error for that object:

.entries[] | select(.icon | try contains("BBC")) | .uuid

like image 180
AKstat Avatar answered Nov 18 '22 17:11

AKstat


You can preselect only objects that have the icon key with has("icon").

From the jq 1.5 Manual:

has(key)

The builtin function has returns whether the input object has the given key, or the input array has an element at the given index.

jq '.entries[] | select(has("icon")) | select(.icon | contains("BBC")).uuid' file

However, it will output an error if your object has "icon":null in which case you could use:

jq '.entries[] | select(.icon != null) | select(.icon | contains("BBC")).uuid' file
like image 5
mickp Avatar answered Nov 18 '22 18:11

mickp