
Ich versuche derzeit, die Ausgabe von lsblk mit jq zu analysieren und sie basierend auf einigen Kriterien zu filtern.
Gegeben ist die folgende Beispielausgabe:
{
"blockdevices": [
{
"name": "/dev/sda",
"fstype": null,
"size": "931.5G",
"mountpoint": null,
"children": [
{
"name": "/dev/sda1",
"fstype": "ntfs",
"size": "50M",
"mountpoint": null
},{
"name": "/dev/sda2",
"fstype": "ntfs",
"size": "439.8G",
"mountpoint": null
},{
"name": "/dev/sda3",
"fstype": "vfat",
"size": "512M",
"mountpoint": "/boot/efi"
},{
"name": "/dev/sda4",
"fstype": "ext4",
"size": "491.2G",
"mountpoint": "/"
}
]
},{
"name": "/dev/sdb",
"fstype": "crypto_LUKS",
"size": "200GG",
"mountpoint": null,
"children": [
{
"name": "/dev/mapper/d1",
"fstype": "btrfs",
"size": "200G",
"mountpoint":[
null
]
}
]
},{
"name": "/dev/sdc",
"fstype": "crypto_LUKS",
"size": "100G",
"mountpoint": null,
"children": [
{
"name": "/dev/mapper/abc2",
"fstype": "btrfs",
"size": "100GG",
"mountpoint": "/mnt/test"
}
]
}
]
}
Ich möchte alle Top-Level-Geräte durchgehen, die den fstype „crypto_LUKS“ haben. Dann möchte ich für diese Geräte prüfen, ob die untergeordneten Geräte (falls vorhanden) einen Einhängepunkt (nicht null) haben. Schließlich möchte ich den Namen des Top-Level-Geräts zurückgeben, das beide Kriterien erfüllt.
Für das obige Beispiel würde also nur 1 Übereinstimmung zurückgegeben:
/dev/sdc /dev/mapper/d1
.
Das /dev/sdc
Gerät wird nicht zurückgegeben, da der Einhängepunkt des untergeordneten Geräts null/leer ist.
Das habe ich bisher schon bekommen:
lsblk -Jpo NAME,FSTYPE,SIZE,MOUNTPOINT | jq -r '.blockdevices[] | select(.fstype == "crypto_LUKS") '
Dies prüft jedoch nur die crypto_LUKS-Kriterien und nicht die Einhängepunkte der untergeordneten Elemente. Außerdem wird der gesamte Array-Eintrag gedruckt, statt nur die beiden Werte.
Wie kann ich das lösen?
Antwort1
So erhalten Sie den Namen des Blockgeräts und jedes seiner untergeordneten Einhängepunkte ungleich Null als tabulatorgetrennte Liste:
jq -r '
.blockdevices[] | select(.fstype == "crypto_LUKS") as $dev |
$dev.children[]? | select(.mountpoint | type == "string") as $mp |
[ $dev.name, $mp.name ] | @tsv'
Da ein „Null-Einhängepunkt“ eigentlich nichts null
anderes als ein Array mit einem einzelnen null
Wert ist, teste ich stattdessen, ob der Einhängepunkt ein String ist oder nicht.
Angesichts der Daten in der Frage würde dies ergeben
/dev/sdc /dev/mapper/abc2
So rufen Sie die Blockgeräteobjekte ab, die die Kriterien erfüllen (falls Sie mit „das gesamte Array“ das meinen):
jq '.blockdevices[] |
select(.fstype == "crypto_LUKS" and
any(.children[]?; .mountpoint | type == "string"))'
Dies gibt das Blockgeräteobjekt zurück, das den fstype
Wert hat crypto_LUKS
und das mindestens ein children
Element mit einem mountpoint
Zeichenfolgenwert hat.
Angesichts der Daten in der Frage würde dies ergeben
{
"name": "/dev/sdc",
"fstype": "crypto_LUKS",
"size": "100G",
"mountpoint": null,
"children": [
{
"name": "/dev/mapper/abc2",
"fstype": "btrfs",
"size": "100GG",
"mountpoint": "/mnt/test"
}
]
}