I have an input:
$ ip -json route show > ip_routes.json
$ cat ip_routes.json # I've pretty printed this for easier reading.
[
{
"dst": "default",
"gateway": "10.1.201.1",
"dev": "eth0"
},
{
"dst": "10.1.201.0/24",
"dev": "eth0",
"prefsrc": "10.1.201.74"
},
{
"dst": "10.1.202.0/24",
"dev": "eth0",
"prefsrc": "10.1.202.74"
},
{
"dst": "10.244.0.0/24",
"dev": "cni0",
"prefsrc": "10.244.0.1"
},
{
"dst": "10.244.0.0/22",
"dev": "cni0",
"scope": "link",
"flags": []
}
]
I can do a query where dev is eth0 and not the default gateway:
$ jq '. [] | if .dev == "eth0" and .dst != "default" then . else empty end' ip_routes.json
{
"dst": "10.1.201.0/24",
"dev": "eth0",
"prefsrc": "10.1.201.74"
}
{
"dst": "10.1.202.0/24",
"dev": "eth0",
"prefsrc": "10.1.202.74"
}
If I try to select specific properties in the output their association with the object is lost:
jq '. [] | if .dev == "eth0" and .dst != "default" then .dev, .prefsrc else empty end' ip_routes.json
"eth0"
"10.1.201.74"
"eth0"
"10.1.202.74"
How do get something like this?
[
{
"eth0",
"10.1.201.74"
}
,
{
"eth0",
"10.1.202.74"
}
]
https://jqplay.org/s/GsAwBlKJJ92DNAO
The solution presented by https://stackoverflow.com/users/2158479/pmf does what I intended even though the wording of the question was vague.
$ jq '. | map(select(.dev == "eth0" and .dst != "default") | {dev, prefsrc})' ip_routes.json
[
{
"dev": "eth0",
"prefsrc": "10.1.201.74"
},
{
"dev": "eth0",
"prefsrc": "10.1.202.74"
}
]
How do get something like this?
[ { "eth0", "10.1.201.74" } , { "eth0", "10.1.202.74" } ]
This is not valid JSON. Curly braces surround objects, and objects contain key-value pairs: {"key1": "value1", "key2": "value2"}
. Arrays only have values (and an implicit index), and are surrounded by square brackets: ["value1", "value2"]
.
Then, with .[]
you destructure the outer array. Use map
to retain it. Also, the if
expression can replaced with select
as you only need one of the branches ("unselected" items are filtered out automatically).
Getting an array of objects using {dev, prefsrc}
:
map(select(.dev == "eth0" and .dst != "default") | {dev, prefsrc})
[
{
"dev": "eth0",
"prefsrc": "10.1.201.74"
},
{
"dev": "eth0",
"prefsrc": "10.1.202.74"
}
]
Getting an array of arrays using [.dev, .prefsrc]
:
map(select(.dev == "eth0" and .dst != "default") | [.dev, .prefsrc])
[
[
"eth0",
"10.1.201.74"
],
[
"eth0",
"10.1.202.74"
]
]