JQ - 如何在不知道键的情况下过滤内部数组中的值

jq - how to filter values in an inner array without knowing the key

提问人:Stefan Lipinski 提问时间:6/15/2022 更新时间:11/18/2023 访问量:626

问:

我有以下JSON:

{
  "ids": {
    "sda": [
      "scsi-0QEMU_QEMU_HARDDISK_drive-scsi2"
    ],
    "sdb": [
      "scsi-0QEMU_QEMU_HARDDISK_drive-scsi0"
    ],
    "sdb1": [
      "lvm-pv-uuid-lvld3A-oA4k-hC19-DXzv-D0Fq-xyME-BwgJid",
      "scsi-0QEMU_QEMU_HARDDISK_drive-scsi0-part1"
    ],
    "sdc": [
      "lvm-pv-uuid-pWes2W-dgYF-l8hG-La48-9ozH-hPdU-MOkOtf",
      "scsi-0QEMU_QEMU_HARDDISK_drive-scsi1"
    ]
  }
}

我想实现的是搜索内部数组的值并得到结果。.*scsi0$sdb

json 选择 jq

评论


答:

0赞 0stone0 6/15/2022 #1
.ids | to_entries[] | select(.value[] | test(".*scsi0$")) | .key

如果数组中的任何值与您的正则表达式匹配,将打印密钥。

如果没有匹配项,则不会有输出。


to_entries用于轻松捕获对象的关键。

select筛选值

.value[] | test(".*scsi0$")将每个值检查为正则表达式

.key我们显示结果的关键


在线试用

评论

1赞 Stefan Lipinski 6/15/2022
也可以,但我接受了上面的答案,因为它更详细。但感谢您的贡献。
0赞 0stone0 6/15/2022
当然是 m8,不知道为什么,有几个指向具有相同答案的文档的链接,很好。.
2赞 bloodyKnuckles 6/15/2022 #2

使用 JSON jq endswith 筛选结果:

.ids | to_entries[] | select(.value[] | endswith("scsi0")) | .key

结果:

"sdb"

在这里试试:https://jqplay.org/s/DAhKosXXgiA


让我们来分解一下......

首先 get ,返回:.ids

{
  "sda": [
    "scsi-0QEMU_QEMU_HARDDISK_drive-scsi2"
  ],
  "sdb": [
    "scsi-0QEMU_QEMU_HARDDISK_drive-scsi0"
  ],
  "sdb1": [
    "lvm-pv-uuid-lvld3A-oA4k-hC19-DXzv-D0Fq-xyME-BwgJid",
    "scsi-0QEMU_QEMU_HARDDISK_drive-scsi0-part1"
  ],
  "sdc": [
    "lvm-pv-uuid-pWes2W-dgYF-l8hG-La48-9ozH-hPdU-MOkOtf",
    "scsi-0QEMU_QEMU_HARDDISK_drive-scsi1"
  ]
}

...然后将结果通过管道传递给 to_entries 函数,以将其转换为对象数组。{key, value}

.ids | to_entries返回:

[
  {
    "key": "sda",
    "value": [
      "scsi-0QEMU_QEMU_HARDDISK_drive-scsi2"
    ]
  },
  {
    "key": "sdb",
    "value": [
      "scsi-0QEMU_QEMU_HARDDISK_drive-scsi0"
    ]
  },
  {
    "key": "sdb1",
    "value": [
      "lvm-pv-uuid-lvld3A-oA4k-hC19-DXzv-D0Fq-xyME-BwgJid",
      "scsi-0QEMU_QEMU_HARDDISK_drive-scsi0-part1"
    ]
  },
  {
    "key": "sdc",
    "value": [
      "lvm-pv-uuid-pWes2W-dgYF-l8hG-La48-9ozH-hPdU-MOkOtf",
      "scsi-0QEMU_QEMU_HARDDISK_drive-scsi1"
    ]
  }
]

...接下来,使用 Iterator 运算符流式传输对象列表。.[]

.ids | to_entries[]返回:

{
  "key": "sda",
  "value": [
    "scsi-0QEMU_QEMU_HARDDISK_drive-scsi2"
  ]
}
{
  "key": "sdb",
  "value": [
    "scsi-0QEMU_QEMU_HARDDISK_drive-scsi0"
  ]
}
{
  "key": "sdb1",
  "value": [
    "lvm-pv-uuid-lvld3A-oA4k-hC19-DXzv-D0Fq-xyME-BwgJid",
    "scsi-0QEMU_QEMU_HARDDISK_drive-scsi0-part1"
  ]
}
{
  "key": "sdc",
  "value": [
    "lvm-pv-uuid-pWes2W-dgYF-l8hG-La48-9ozH-hPdU-MOkOtf",
    "scsi-0QEMU_QEMU_HARDDISK_drive-scsi1"
  ]
}

...并从值流中进行选择,其中值以“scsi0”结尾,.ids | to_entries[] | select(.value[])select(.value[] | endswith("scsi0"))

{
  "key": "sdb",
  "value": [
    "scsi-0QEMU_QEMU_HARDDISK_drive-scsi0"
  ]
}

...最后,获取键值。

.ids | to_entries[] | select(.value[] | endswith("scsi0")) | .key返回:

"sdb"

命令行:

jq '.ids | to_entries[] | select(.value[] | endswith("scsi0")) | .key'

在这里试试:https://jqplay.org/s/DAhKosXXgiA