JL Peyret
JL Peyret

Reputation: 12204

How do I extract by key in an object, on a sibling?

How can I use jq to qualify filters on just some key values and reshape a hierarchy?

this is the input, from an Ansible log:

(the log format was by setting env variable ANSIBLE_STDOUT_CALLBACK=json)

I want to associate the name with the msg, but only for host 192.169.1.170.

{
    "plays": [
        {
            "tasks": [
                {
                    "hosts": {
                        "192.169.1.70": {
                            "msg": "inventory_hostname:192.169.1.70:"
                        },
                        "dontcare": {
                            "msg": "dont want to see this:"
                        }
                    },
                    "task": {
                        "name": "debug inventory_hostname"
                    }
                },
                {
                    "hosts": {
                        "192.169.1.70": {
                            "msg": "All items completed"
                        }
                    },
                    "task": {
                        "name": "install system-level components"
                    }
                }
            ]
        }
    ]
}

desired output:

{
  "name": "debug inventory_hostname",
  "msg": "inventory_hostname:192.169.1.70:"
},
{
  "name": "install system-level components",
  "msg": "All items completed"
}

I can extract some data, but I can't nest the sibling host msg, and I can't limit my search to just my host of interest, 192.169.1.70:

jq '.plays[] | .tasks[] | .task,.hosts' ansible.json

{
  "name": "debug inventory_hostname"
}
{
  "192.169.1.70": {
    "msg": "inventory_hostname:192.169.1.70:"
  },
  "dontcare": {
    "msg": "dont want to see this:"
  }
}
{
  "name": "install system-level components"
}
{
  "192.169.1.70": {
    "msg": "All items completed"
  }
}

Whenever I try something to qualify the hosts key I want, .hosts["192.169.1.170"] or .hosts.192.169.1.170 or .hosts{"192.169.1.170"}, .hosts("192.169.1.170"), I get either null or compile errors. Most of the sample jq code concerns filtering arrays, not accessing hashmaps/dictionaries.

And, how would I grab the sibling data for the name and bring in the same object, as above?

Upvotes: 0

Views: 99

Answers (1)

oguz ismail
oguz ismail

Reputation: 50795

I think you're looking for select and addition operator (+).

.plays[].tasks[]
| select(.hosts | has("192.169.1.70"))
| .task + .hosts."192.169.1.70"

REPL demo

Upvotes: 2

Related Questions