[Cialug] JSON Question

Jeffrey Ollie jeff at ocjtech.us
Fri Oct 4 18:59:48 UTC 2019


I think that to_entries will do what you need:

jq '.tasks[0].hosts | to_entries | map({host: .key, failed:
.value.failed})' test-data.json
[
  {
    "host": "hostone.example.com",
    "failed": false
  },
  {
    "host": "hosttwo.example.com",
    "failed": true
  }
]

On Fri, Oct 4, 2019 at 1:41 PM Todd Walton <tdwalton at gmail.com> wrote:

> I have a test JSON file that closely resembles the format of a for-real
> JSON stream I get out of Ansible. It does something aggravating: it returns
> a set of host data in a JSON object that doesn't include a unique
> identifier for the host. Instead, it uses a key:value pair with the key
> being the hostname and the value being a JSON object with all the
> attributes of the host. Here's my test file, check it out:
>
> todd $ jq '.' test-data.json
> {
>   "tasks": [
>     {
>       "hosts": {
>         "hostone.example.com": {
>           "_ansible_no_log": false,
>           "_ansible_parsed": true,
>           "action": "command",
>           "changed": true,
>           "failed": false,
>           "msg": "non-zero return code",
>           "stderr": "",
>           "stderr_lines": [],
>           "stdout": "",
>           "stdout_lines": []
>         },
>         "hosttwo.example.com": {
>           "_ansible_no_log": false,
>           "_ansible_parsed": true,
>           "action": "command",
>           "changed": true,
>           "failed": true,
>           "msg": "non-zero return code",
>           "stderr": "",
>           "stderr_lines": [],
>           "stdout": "",
>           "stdout_lines": []
>         }
>       }
>     }
>   ]
> }
>
> jq has a feature whereby if you append '.[]' to an object it will return
> just the values of the object. So in this case:
>
> todd $ jq '.tasks[].hosts[]' test-data.json
> {
>   "_ansible_no_log": false,
>   "_ansible_parsed": true,
>   "action": "command",
>   "changed": true,
>   "failed": false,
>   "msg": "non-zero return code",
>   "stderr": "",
>   "stderr_lines": [],
>   "stdout": "",
>   "stdout_lines": []
> }
> {
>   "_ansible_no_log": false,
>   "_ansible_parsed": true,
>   "action": "command",
>   "changed": true,
>   "failed": true,
>   "msg": "non-zero return code",
>   "stderr": "",
>   "stderr_lines": [],
>   "stdout": "",
>   "stdout_lines": []
> }
>
> I get the set of attributes for each host, but not the key names, i.e. not
> the hostnames. But let's say I want to return the value of "failed" for
> each host, associating each hostname with its value for "failed". So,
> something like this:
>
> {
>   "hostone.example.com": false
>   "hosttwo.example.com": true
> }
>
> or
>
> {
>   "hostone.example.com": {
>     "failed": false
>   },
>   "hosttwo.example.com": {
>     "failed": true
>   }
> }
>
> How do I do that? How do I grab that hostname and use it in the later
> expression? I've tried various things, including piping .tasks[] to a
> custom object with the path I would take to each, but I'm not sure how to
> get just one hostname at a time and query just that one, etc. Any
> suggestions?
>
> --
> Todd
> _______________________________________________
> Cialug mailing list
> Cialug at cialug.org
> https://www.cialug.org/cgi-bin/mailman/listinfo/cialug
>


-- 
Jeff Ollie
The majestik møøse is one of the mäni interesting furry animals in Sweden.


More information about the Cialug mailing list