I have a json like this but much longer:
[
{
"id": "123",
"name": "home network configuration",
"description": "home utilities",
"definedRanges": [
{
"id": "6500b67e",
"name": "100-200",
"beginIPv4Address": "192.168.090.100",
"endIPv4Address": "192.168.090.200",
"state": "UNALLOCATED"
}
]
},
{
"id": "456",
"name": "lab network configuration",
"description": "lab experiments",
"definedRanges": [
{
"id": "1209b90d",
"name": "100-200",
"beginIPv4Address": "192.168.090.100",
"endIPv4Address": "192.168.090.200",
"state": "ALLOCATED"
},
{
"id": "99e08ca4",
"name": "100-200",
"beginIPv4Address": "192.168.090.100",
"endIPv4Address": "192.168.090.200",
"state": "UNALLOCATED"
}
]
}
]
I'd like to query with jq and obtain the following:
[
{
"name": "home network configuration"
"definedRanges": [
{
"name": "100-200",
"beginIPv4Address": "192.168.090.100",
"endIPv4Address": "192.168.090.200",
}
]
},
{
"name": "lab network configuration",
"definedRanges": [
{
"name": "100-200",
"beginIPv4Address": "192.168.090.100",
"endIPv4Address": "192.168.090.200",
},
{
"name": "100-200",
"beginIPv4Address": "192.168.090.100",
"endIPv4Address": "192.168.090.200",
}
]
}
]
or even this:
[
{
"name": "home network configuration",
"definedRanges.name": "100-200",
"definedRanges.beginIPv4Address": "192.168.090.100",
"definedRanges.endIPv4Address": "192.168.090.200",
},
{
"name": "lab network configuration",
"definedRanges.name": "100-200",
"beginIPv4Address": "192.168.090.100",
"endIPv4Address": "192.168.090.200",
},
{
"name": "lab network configuration",
"beginIPv4Address": "192.168.090.100",
"endIPv4Address": "192.168.090.200",
}
]
So far I was able to extract the network name at the first level with:
.[] | {name}
I could also extract the definedRanges with:
.[].definedRanges[] | {name,beginIPv4Address,endIPv4Address}
But I can't figure out how to merge the two with jq.
I solved the problem with a very simple python script (7 lines of code) but now I'd like to understand how to do the same with jq, out of curiosity.
CodePudding user response:
Well, you were close. Here's how you put those together:
map({name, definedRanges: .definedRanges | map({name, beginIPv4Address, endIPv4Address})})
CodePudding user response:
The 'or even this' can be achieved using:
map(.name as $name | .definedRanges[] | { name, beginIPv4Address, endIPv4Address} | with_entries(.key = "definedRanges." .key) | .name = $name)
Which yields:
[
{
"definedRanges.name": "100-200",
"definedRanges.beginIPv4Address": "192.168.090.100",
"definedRanges.endIPv4Address": "192.168.090.200",
"name": "home network configuration"
},
{
"definedRanges.name": "100-200",
"definedRanges.beginIPv4Address": "192.168.090.100",
"definedRanges.endIPv4Address": "192.168.090.200",
"name": "lab network configuration"
},
{
"definedRanges.name": "100-200",
"definedRanges.beginIPv4Address": "192.168.090.100",
"definedRanges.endIPv4Address": "192.168.090.200",
"name": "lab network configuration"
}
]