I am fetching droplet lists from the DigitalOcean JSON API and using jq map to transform the response into just the info I need.
I want to be able to add an optional key & value pair to my new object, based on whether the response contains a key with a certain value.
When using select()
if the response doesn't contain a match, the whole droplet entry is removed from my new object, rather than just the key.
How can I filter a single key rather than the whole entry?
In detail:
The response for a single droplet looks like this:
"id": 12345678,
"name": "my-droplet",
...
"networks": {
"v4": [
{
"ip_address": "123.456.78.90",
"netmask": "255.255.240.0",
"gateway": "123.123.0.1",
"type": "public"
},
{
"ip_address": "10.123.45.67",
"netmask": "255.255.0.0",
"gateway": "10.123.0.1",
"type": "private"
}
],
"v6": []
},
...
I want to transform this into an object of the form:
{
"id": 12345678,
"name": "my-droplet",
"public_ip": "123.456.78.90",
"private_ip" "10.123.45.67"
}
All droplets have a public IP, but the private IP is optional.
I have this, which ignores the optional private IP, and works fine so far:
jq '.droplets | map({id: .id, name: .name, status: .status, public_ip: .networks.v4[] | select(.type=="public") | .ip_address})'
However, once I add in the private IP, any droplet that doesn't have one goes missing from the response:
jq '.droplets | map({id: .id, name: .name, status: .status, public_ip: .networks.v4[] | select(.type=="public") | .ip_address, private_ip: .networks.v4[] | select(.type=="private") | .ip_address})'
I think I need to use concatenation or conditionals some how, but I can't quite figure out the syntax.
Note: I found this similar question, but it doesn't include changing the name of the key: denormalizing JSON with jq