From this file:
[
{
"network": "X.X.X.1",
"defaultGateway": "X.X.X.X",
"ipAddressTab": [
{
"foo1": "10.0.0.1",
"foo2": "network",
"status": "reserved",
"foo4": null,
"foo5": null,
"foo6": null,
"foo7": null,
"foo8": null,
"foo9": null,
"foo10": null,
"foo11": null
},
{
"foo1": "10.0.0.2",
"foo2": "network",
"status": "reserved",
"foo4": null,
"foo5": null,
"foo6": null,
"foo7": null,
"foo8": null,
"foo9": null,
"foo10": null,
"foo11": null
},
{
"foo1": "10.0.0.3",
"foo2": "network",
"status": "reserved",
"foo4": null,
"foo5": null,
"foo6": null,
"foo7": null,
"foo8": null,
"foo9": null,
"foo10": null,
"foo11": null
},
{
"foo1": "10.0.0.4",
"status": "available"
},
{
"foo1": "10.0.0.5",
"status": "available"
},
{
"foo1": "10.0.0.6",
"status": "available"
},
{
"foo1": "10.0.0.7",
"status": "available"
}
],
"full": false,
"id": "xxx"
},
{
"network": "X.X.X.2",
"defaultGateway": "X.X.X.X",
"ipAddressTab": [
{
"foo1": "10.0.0.1",
"foo2": "network",
"status": "reserved",
"foo4": null,
"foo5": null,
"foo6": null,
"foo7": null,
"foo8": null,
"foo9": null,
"foo10": null,
"foo11": null
},
{
"foo1": "10.0.0.2",
"foo2": "network",
"status": "reserved",
"foo4": null,
"foo5": null,
"foo6": null,
"foo7": null,
"foo8": null,
"foo9": null,
"foo10": null,
"foo11": null
},
{
"foo1": "10.0.0.3",
"foo2": "network",
"status": "reserved",
"foo4": null,
"foo5": null,
"foo6": null,
"foo7": null,
"foo8": null,
"foo9": null,
"foo10": null,
"foo11": null
},
{
"foo1": "10.0.0.4",
"status": "available"
},
{
"foo1": "10.0.0.5",
"status": "available"
},
{
"foo1": "10.0.0.6",
"status": "available"
},
{
"foo1": "10.0.0.7",
"status": "available"
}
],
"full": false,
"id": "xxx"
}
]
# Just an example, there is more lines in my file
I can keep the informations that I want:
cat myfile | jq 'map({network, full})'
[
{
"network": "X.X.X.1",
"full": false
},
{
"network": "X.X.X.2",
"full": false
}
]
Now I'm looking for a tip to count and display some values. For example, I would like to display the number of reserved, allocated and available like that:
[
{
"network": "X.X.X.1",
"full": false
reserved: 3
available: 4
},
{
"network": "X.X.X.2",
"full": false
reserved: 3
available: 4
}
]
I've look everywhere and I found no good example to do that...
Some one to show me how can I have this output?
Thanks !
Use reduce
to count statuses.
map({network, full} +
reduce .ipAddressTab[].status as $s ({}; .[$s] += 1))
You can change {}
to {reserved: 0, available: 0}
to maintain a consistent order of keys among all the entries.
One way to do this would be to use a function to count the objects of each type
def f($path; $val): $path | map(select(.status == $val)) | length;
map({network, full, reserved: f(.ipAddressTab; "reserved"), available: f(.ipAddressTab; "available")})
The function f
takes a path and the status string to be looked-up then gets the length of the objects in the array.
With oguz ismail's suggestion to avoid repetition
def f($val): map(select(.status == $val)) | length;
map({network, full} + (.ipAddressTab | { reserved: f("reserved"), available: f("available")}))
When counting a potentially large number of objects, it's usually better to use stream-oriented filters so as to avoid constructing arrays. These two are often useful as a pair, though in the present case defining just count/1
by itself would be sufficient:
def sigma(s): reduce s as $x (0; .+$x);
def count(s): sigma(s|1);
To achieve the stated goal, one can now simply write the specification as a program:
map({network,
full,
reserved: count(.ipAddressTab[] | select(.status == "reserved")),
available: count(.ipAddressTab[] | select(.status == "available"))
})
Now for a little jq magic -- no references to specific "status" values at all:
def countStatus($s):
{($s): count(.ipAddressTab[] | select(.status == $s))};
def statuses: [.ipAddressTab[].status] | unique;
map( {network, full}
+ ([countStatus(statuses[])] | add) )
In a comment, a question about showing total_available
was asked. To add a total_available
key to each object, you could append the following to either of the above pipelines:
| {total_available: sigma(.[] | .available)} as $total
| map(. + $total)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.