hedda hedda - 4 months ago 15
Linux Question

Return entire object from Array based on key value in object using jq

I have a .json file that I would like to filter through jq to return the entire object in the array if the key value in that object equals 'failed'. How would I do this ?

Example json:

"version": "0.26.0",
"controls": [{
"id": "os-1.0",
"status": "passed",
"code_desc": "File /etc/profile content should match /umask\\s*022/",
"profile_id": "test"
}, {
"id": "os-1.0",
"status": "passed",
"code_desc": "File /etc/bashrc content should match /umask\\s*022/",
"profile_id": "test"
}, {
"id": "os-1.0",
"status": "failed",
"code_desc": "File /etc/csh.cshrc content should match /umask\\s*022/",
"profile_id": "test"
"message": "\nexpected: \"/sbin/sulogin\"\n got: \n\n(compared using `cmp` matcher)\n"
}]


Output to a new file :

{
"id": "os-1.0",
"status": "failed",
"code_desc": "File /etc/csh.cshrc content should match /umask\\s*022/",
"profile_id": "test"
"message": "\nexpected: \"/sbin/sulogin\"\n got: \n\n(compared using `cmp` matcher)\n"
}

Answer

The text shown as JSON is invalid as JSON. Assuming it is fixed to have the structure {"version": _, "controls": _}, the following filter would yield the result shown below:

.controls[] | select(.status == "failed")

Output:

{
  "id": "os-1.0",
  "status": "failed",
  "code_desc": "File /etc/csh.cshrc content should match /umask\\s*022/",
  "profile_id": "test",
  "message": "\nexpected: \"/sbin/sulogin\"\n     got: \n\n(compared using `cmp` matcher)\n"
}

Note: For robustness you might want to use .status? instead of .status.