JQ将对象映射到具有条件的数组。

13

我有这个输入数据:

[
  {
    "attributes": {
      "created": "2021-10-18T12:02:39+00:00",
      "enabled": true,
      "expires": null,
      "notBefore": null
    },
    "contentType": null,
    "id": "https://kjkljk./secrets/-/1",
    "managed": null,
    "name": "pw",
    "tags": {}
  },
  {
    "attributes": {
      "created": "2021-10-18T12:06:16+00:00",
      "enabled": true,
      "expires": null,
      "notBefore": null
    },
    "contentType": "",
    "id": "https://kjklj./secrets/-/2",
    "managed": null,
    "name": "pw",
    "tags": {}
  }
]

我需要使用jq将启用(enabled)设置为true的id值提取到一个新数组中。这是我目前的代码:

.[] | select(any(.attributes; .enabled== true)) | {id} 

但它只会导致这个结果:
{
  "id": "https://kjkljk./secrets/-/1"
}
{
  "id": "https://kjklj./secrets/-/2"
}

如何将这两个对象转换为字符串数组呢?
[
  "id": "https://kjkljk./secrets/-/1",
  "id": "https://kjklj./secrets/-/2"
]

1
[ "id": "https://kjkljk./secrets/-/1", "id": "https://kjklj./secrets/-/2" ] 不是有效的 JSON。你说“字符串数组”,所以你是不是想说 [ "https://kjkljk./secrets/-/1", "https://kjklj./secrets/-/2" ] - ikegami
4个回答

20

使用 map 而不是 .[] 来保留数组:

map(select(any(.attributes; .enabled)) | {id})
[
  {"id": "https://kjkljk./secrets/-/1"},
  {"id": "https://kjklj./secrets/-/2"}
]

演示

请注意,这将生成一个对象数组[{…},{…}],我认为这就是您所请求的,尽管在您期望的输出中,您缺少了花括号{ }。要创建一个“字符串数组”,请使用.id而不是{id},像这样:

map(select(any(.attributes; .enabled)) | .id)
[
  "https://kjkljk./secrets/-/1",
  "https://kjklj./secrets/-/2"
]

演示

(此外,您可以使用.enabled代替.enabled == true)


7

大概是这样的:

$ jq '[.[] | select(.attributes.enabled) | .id]' input.json
[
  "https://kjkljk./secrets/-/1",
  "https://kjklj./secrets/-/2"
]

可以缩短并且更易读,如下所示:map(select(.attributes.enabled).id) - A.H.

1
这应该可以工作:
map(select(any(.attributes; .enabled == true)) | .id)

解释:与使用.[]分割数组不同,map()函数保留了数组结构,但对元素进行操作。使用.id而不是{id}可以避免为每个选定的值创建一个字典。

如果我理解正确,您还可以将any(.attributes; .enabled == true)替换为.attributes.enabled == true


1

如之前的回答和评论所述,您希望得到的输出不是有效的JSON格式。

因此,您有两个选择。我将您的输入文件粘贴在SO-70302009.json中。

  1. 将id行包装为对象jq 'map({id: select(any(.attributes; .enabled)) | .id})' "./SO-70302009.json",得到:
[
  {
    "id": "https://kjkljk./secrets/-/1"
  },
  {
    "id": "https://kjklj./secrets/-/2"
  }
]

使用以下命令创建一个id数组:jq '{ ids: map(select(any(.attributes; .enabled)) | .id) }' "./SO-70302009.json",输出结果如下:
{
  "ids": [
    "https://kjkljk./secrets/-/1",
    "https://kjklj./secrets/-/2"
  ]
}

谢谢,但愿我45分钟前就能找到这个! - Tom

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接