Example JSON with many properties at various levels elided:
{
"partitiontable": {
"label": "gpt",
"partitions": [
{
"node": "/dev/nvme0n1p1",
"start": 2048,
"size": 204801
},
{
"node": "/dev/nvme0n1p2",
"start": 208896,
"size": 4097
},
{
"node": "/dev/nvme0n1p3",
"start": 243712,
"size": 65501185
},
{
"node": "/dev/nvme0n1p4",
"start": 65810432,
"size": 3841118208
}
]
}
}
within each element of the 'partitions' array, I'd like to perform the property-creation operation: .end = .start + .size resulting in a document such as:
{
"partitiontable": {
"label": "gpt",
"partitions": [
{
"end": 206849,
"node": "/dev/nvme0n1p1",
"start": 2048,
"size": 204801
},
{
"end": 212993,
"node": "/dev/nvme0n1p2",
"start": 208896,
"size": 4097
},
{
"end": 65744897,
"node": "/dev/nvme0n1p3",
"start": 243712,
"size": 65501185
},
{
"end": 3906928640,
"node": "/dev/nvme0n1p4",
"start": 65810432,
"size": 3841118208
}
]
}
}
There could be many other properties within each object that I'll need to preserve (hopefully without explicit enumeration).
I've attempted straight-out .partitiontable.partitions[].end = .size + .start, but those 'end' properties wind up null, I'm presuming because there's no 'context'. I've also tried using the '..' operator to recurse, but I only get the local-scoping object as output. (jq '.. | objects | select(.start) | .end = .start + .size' results in the array objects but loses the outer document.)
The update operation |=
is an assignment with the context of the LHS promoted to the RHS. With that, .start
, .size
, and .end
can be resolved correctly.
jq '.partitiontable.partitions[] |= (.end = .start + .size)'
{
"partitiontable": {
"label": "gpt",
"partitions": [
{
"node": "/dev/nvme0n1p1",
"start": 2048,
"size": 204801,
"end": 206849
},
{
"node": "/dev/nvme0n1p2",
"start": 208896,
"size": 4097,
"end": 212993
},
{
"node": "/dev/nvme0n1p3",
"start": 243712,
"size": 65501185,
"end": 65744897
},
{
"node": "/dev/nvme0n1p4",
"start": 65810432,
"size": 3841118208,
"end": 3906928640
}
]
}
}