
Actualmente estoy intentando analizar la salida de lsblk con jq y filtrarla según algunos criterios.
Dado el siguiente ejemplo de salida:
{
"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"
}
]
}
]
}
Quiero repasar todos los dispositivos de nivel superior que tienen fstype "crypto_LUKS". Luego, para esos dispositivos, quiero verificar si los hijos (si están presentes) tienen un punto de montaje (no nulo). Finalmente quiero devolver el nombre del dispositivo de nivel superior que coincida con ambos criterios.
Entonces, para el ejemplo anterior, solo se devolverá 1 coincidencia:
/dev/sdc /dev/mapper/d1
.
El /dev/sdc
dispositivo no se devolverá porque el punto de montaje del dispositivo secundario es nulo/vacío.
Ya tengo esto hasta ahora:
lsblk -Jpo NAME,FSTYPE,SIZE,MOUNTPOINT | jq -r '.blockdevices[] | select(.fstype == "crypto_LUKS") '
Pero esto sólo comprueba los criterios crypto_LUKS, y no los puntos de montaje de los hijos. También imprime la entrada completa de la matriz en lugar de solo los dos valores.
¿Como puedo resolver esto?
Respuesta1
Para obtener el nombre del dispositivo de bloque y cada uno de sus puntos de montaje secundarios no nulos como una lista delimitada por tabulaciones:
jq -r '
.blockdevices[] | select(.fstype == "crypto_LUKS") as $dev |
$dev.children[]? | select(.mountpoint | type == "string") as $mp |
[ $dev.name, $mp.name ] | @tsv'
Dado que un "punto de montaje nulo" en realidad no es null
sino una matriz de un solo null
valor, en lugar de eso estoy probando si el punto de montaje es una cadena o no.
Dados los datos de la pregunta, esto devolvería
/dev/sdc /dev/mapper/abc2
Para obtener los objetos del dispositivo de bloque que cumplen con los criterios (si eso es lo que quiere decir con "toda la matriz"):
jq '.blockdevices[] |
select(.fstype == "crypto_LUKS" and
any(.children[]?; .mountpoint | type == "string"))'
Esto devuelve el objeto de dispositivo de bloque que tiene el fstype
valor crypto_LUKS
y que tiene al menos un children
elemento con mountpoint
una cadena.
Dados los datos de la pregunta, esto devolvería
{
"name": "/dev/sdc",
"fstype": "crypto_LUKS",
"size": "100G",
"mountpoint": null,
"children": [
{
"name": "/dev/mapper/abc2",
"fstype": "btrfs",
"size": "100GG",
"mountpoint": "/mnt/test"
}
]
}