I have JSON output as shown below (the output of lsblk
, greatly simplified). I need to generate CSV output which shows the name of a disk, together with a list of mount points, if any. I can generate this for simple cases, but the problem is that there's a recursive children list, containing additional mountpoints, which I don't know how to handle.
There are a couple of other SO questions which ask specifically about parsing lsblk
output, but they show a simpler (old?) lsblk
output, which is flat (and with mountpoints which aren't arrays).
For the example below, I'd like to get CSV output that looks like (without the comments, obviously):
"sda" # no mountpoints
"sdb","foo1","foo2","foo3" # no top-level mountpoint, 3 [grand]children
Note:
- All
mountpoints
are arrays. Presumably they can contain more than one element (or no elements), but I've never seen this - Any
mountpoints
can containnull
entries, but it seems like the array is always present - The
blockdevices
object contains a list, but only entries of typedisk
are relevant
Any help much appreciated - I've spent several hours trying to find a walk/recurse solution which handles the children.
{
"blockdevices": [
{
"type": "disk",
"name": "sda",
"etc" : "ignore",
"mountpoints": [ null ]
},{
"type": "loop",
"etc" : "ignore everything"
},{
"type": "disk",
"name": "sdb",
"etc" : "ignore",
"mountpoints": [ null ],
"children": [
{
"name": "ignore",
"etc" : "ignore",
"mountpoints": [ "foo1" ]
},{
"name": "ignore",
"etc" : "ignore",
"mountpoints": [ null ],
"children": [
{
"name": "ignore",
"etc" : "ignore",
"mountpoints": [ "foo2" ]
},{
"name": "ignore",
"etc" : "ignore",
"mountpoints": [ "foo3" ]
}
]
}
]
}
]
}
I have JSON output as shown below (the output of lsblk
, greatly simplified). I need to generate CSV output which shows the name of a disk, together with a list of mount points, if any. I can generate this for simple cases, but the problem is that there's a recursive children list, containing additional mountpoints, which I don't know how to handle.
There are a couple of other SO questions which ask specifically about parsing lsblk
output, but they show a simpler (old?) lsblk
output, which is flat (and with mountpoints which aren't arrays).
For the example below, I'd like to get CSV output that looks like (without the comments, obviously):
"sda" # no mountpoints
"sdb","foo1","foo2","foo3" # no top-level mountpoint, 3 [grand]children
Note:
- All
mountpoints
are arrays. Presumably they can contain more than one element (or no elements), but I've never seen this - Any
mountpoints
can containnull
entries, but it seems like the array is always present - The
blockdevices
object contains a list, but only entries of typedisk
are relevant
Any help much appreciated - I've spent several hours trying to find a walk/recurse solution which handles the children.
{
"blockdevices": [
{
"type": "disk",
"name": "sda",
"etc" : "ignore",
"mountpoints": [ null ]
},{
"type": "loop",
"etc" : "ignore everything"
},{
"type": "disk",
"name": "sdb",
"etc" : "ignore",
"mountpoints": [ null ],
"children": [
{
"name": "ignore",
"etc" : "ignore",
"mountpoints": [ "foo1" ]
},{
"name": "ignore",
"etc" : "ignore",
"mountpoints": [ null ],
"children": [
{
"name": "ignore",
"etc" : "ignore",
"mountpoints": [ "foo2" ]
},{
"name": "ignore",
"etc" : "ignore",
"mountpoints": [ "foo3" ]
}
]
}
]
}
]
}
Share
Improve this question
asked Nov 20, 2024 at 11:09
QF0QF0
5291 gold badge4 silver badges18 bronze badges
1 Answer
Reset to default 1Probably not the cleanest way, but we could:
- Filter on
select(.type == "disk")
to prevent empty starting arrays. - Recursive (
..
) get all.mountpoints
(or empty array as fallback (// []
)) flatten
the arrays to get a single output.- Then remove all
null
from the arrays (values
).
.blockdevices[] | select(.type == "disk") | [
.name,
(.. | (.mountpoints? // []) | flatten[] | values)
]
output:
[
"sda"
]
[
"sdb",
"foo1",
"foo2",
"foo3"
]