Linux

用 jq 解析 lsblk

  • October 21, 2021

我目前正在嘗試使用 jq 解析 lsblk 的輸出並根據某些標準對其進行過濾。

給定以下範例輸出:

{
  "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"
           }
        ]
     }
  ]
}

我想查看所有具有 fstype“crypto_LUKS”的頂級設備。然後,對於這些設備,我想檢查孩子(如果存在)是否有安裝點(不為空)。最後,我想返回與這兩個條件都匹配的頂級設備的名稱。

因此,對於上面的範例,只會返回 1 個匹配項: /dev/sdc /dev/mapper/d1.

由於/dev/sdc子設備的掛載點為空/空,因此不會返回設備。

到目前為止我已經得到了這個:

lsblk -Jpo NAME,FSTYPE,SIZE,MOUNTPOINT | jq -r '.blockdevices[] | select(.fstype == "crypto_LUKS") '

但這僅檢查 crypto_LUKS 標準,而不檢查孩子的掛載點。它還列印整個數組條目,而不僅僅是兩個值。

我該如何解決這個問題?

要獲取塊設備的名稱及其每個非空子掛載點作為製表符分隔的列表:

jq -r '
   .blockdevices[]  | select(.fstype == "crypto_LUKS") as $dev |
   $dev.children[]? | select(.mountpoint | type == "string") as $mp |
   [ $dev.name, $mp.name ] | @tsv'

由於“空掛載點”實際上不是null單個null值的數組,因此我正在測試掛載點是否為字元串。

鑑於問題中的數據,這將返回

/dev/sdc        /dev/mapper/abc2

要獲取滿足條件的塊設備對象(如果這就是“整個數組”的意思):

jq '.blockdevices[] |
   select(.fstype == "crypto_LUKS" and
          any(.children[]?; .mountpoint | type == "string"))'

這將返回塊設備對象,該對象具有該fstypecrypto_LUKS並且至少有一個帶有 a是字元串children的元素。mountpoint

鑑於問題中的數據,這將返回

{
 "name": "/dev/sdc",
 "fstype": "crypto_LUKS",
 "size": "100G",
 "mountpoint": null,
 "children": [
   {
     "name": "/dev/mapper/abc2",
     "fstype": "btrfs",
     "size": "100GG",
     "mountpoint": "/mnt/test"
   }
 ]
}

引用自:https://unix.stackexchange.com/questions/674215