jqを使用したlsblkの解析

jqを使用したlsblkの解析

私は現在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"を使用してすべての親デバイスを確認したいと思います。次に、これらのデバイスのサブデバイス(存在する場合)にマウントポイント(空ではない)があることを確認したいと思います。最後に、これら2つの基準を満たす親デバイスの名前を返したいと思います。

したがって、上記の例では、一致する1つの項目のみが返されます /dev/sdc /dev/mapper/d1

サブデバイスのマウントポイントが空であるため、デバイス/dev/sdcは返されません。

これまで私はこれを得ました:

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

ただし、これはサブキーのマウントポイントではなくcrypto_LUKS基準のみを確認します。また、2 つの値だけでなく、配列項目全体を印刷します。

この問題をどのように解決できますか?

答え1

ブロックデバイスの名前とnull以外の各サブマウントポイントをタブ区切りリストにインポートするには、次の手順を実行します。

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"))'

これにより、fstypeその値を含むブロックデバイスオブジェクトcrypto_LUKSと文字列を含む1つ以上の要素が返されます。childrenmountpoint

質問のデータが与えられると、これは次を返します。

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

関連情報