2

我有这个要转换的 json。

[
  {
    "externalGroup": "another group admins",
    "groupId": "da2e42c8-6423-4d32-99b5-5fc58f9f80b8"
  },
  {
    "externalGroup": "another group users",
    "groupId": "7c69cac1-4a70-4170-8251-cde3762fe498"
  },
  {
    "externalGroup": "my group admin",
    "groupId": "e08a1d9d-f108-4e87-bdb3-ee4f10c6752a"
  },
  {
    "externalGroup": "my group users",
    "groupId": "8370821e-edfa-4615-ac2e-47815b740f40"
  },
  {
    "externalGroup": "some group",
    "groupId": "e08a1d9d-f108-4e87-bdb3-ee4f10c6752a"
  },
  {
    "externalGroup": "some group",
    "groupId": "8370821e-edfa-4615-ac2e-47815b740f40"
  },
  {
    "externalGroup": "some group",
    "groupId": "7c69cac1-4a70-4170-8251-cde3762fe498"
  }
]

我试过这个,非常接近: jq '. | group_by(.externalGroup)[] | {(.[0].externalGroup): map(.groupId)}'

我明白了:

{
  "another group admins": [
    "da2e42c8-6423-4d32-99b5-5fc58f9f80b8"
  ]
}
{
  "another group users": [
    "7c69cac1-4a70-4170-8251-cde3762fe498"
  ]
}
{
  "my group admin": [
    "e08a1d9d-f108-4e87-bdb3-ee4f10c6752a"
  ]
}
{
  "my group users": [
    "8370821e-edfa-4615-ac2e-47815b740f40"
  ]
}
{
  "some group": [
    "e08a1d9d-f108-4e87-bdb3-ee4f10c6752a",
    "8370821e-edfa-4615-ac2e-47815b740f40",
    "7c69cac1-4a70-4170-8251-cde3762fe498"
  ]
}

但这不能用 yq 正确转换。它需要看起来像这样:

{
  "another group admins": [
    "da2e42c8-6423-4d32-99b5-5fc58f9f80b8"
  ],
  "another group users": [
    "7c69cac1-4a70-4170-8251-cde3762fe498"
  ],
  "my group admin": [
    "e08a1d9d-f108-4e87-bdb3-ee4f10c6752a"
  ],
  "my group users": [
    "8370821e-edfa-4615-ac2e-47815b740f40"
  ],
  "some group": [
    "e08a1d9d-f108-4e87-bdb3-ee4f10c6752a",
    "8370821e-edfa-4615-ac2e-47815b740f40",
    "7c69cac1-4a70-4170-8251-cde3762fe498"
  ]
}

为了得到类似的东西:

"another group admins":
  - "da2e42c8-6423-4d32-99b5-5fc58f9f80b8"
"another group users":
  - "7c69cac1-4a70-4170-8251-cde3762fe498"
"my group admin":
  - "e08a1d9d-f108-4e87-bdb3-ee4f10c6752a"
"my group users":
  - "8370821e-edfa-4615-ac2e-47815b740f40"
"some group":
  - "e08a1d9d-f108-4e87-bdb3-ee4f10c6752a",
  - "8370821e-edfa-4615-ac2e-47815b740f40",
  - "7c69cac1-4a70-4170-8251-cde3762fe498"
4

2 回答 2

2

您缺少的部分是from_entries可以从键和值数组构建 JSON 对象。

代替:

jq '. | group_by(.externalGroup)[] | {(.[0].externalGroup): map(.groupId)}'

尝试:

jq 'group_by(.externalGroup) | map({key:.[0].externalGroup, value:map(.groupId)}) | from_entries'
{
  "another group admins": [
    "da2e42c8-6423-4d32-99b5-5fc58f9f80b8"
  ],
  "another group users": [
    "7c69cac1-4a70-4170-8251-cde3762fe498"
  ],
  "my group admin": [
    "e08a1d9d-f108-4e87-bdb3-ee4f10c6752a"
  ],
  "my group users": [
    "8370821e-edfa-4615-ac2e-47815b740f40"
  ],
  "some group": [
    "e08a1d9d-f108-4e87-bdb3-ee4f10c6752a",
    "8370821e-edfa-4615-ac2e-47815b740f40",
    "7c69cac1-4a70-4170-8251-cde3762fe498"
  ]
}

我做了以下更改:

  • 一开始就删除了. |,因为它不会改变任何东西。
  • 删除了[]map(...)改为使用,因为我们想将东西保存在一个数组中以提供给from_entries.
  • 我们不是组装一个单项对象,而是创建{key:..., value:...}对来提供给from_entries.

实际上,我刚刚检查并略微惊讶地发现这add实际上比from_entries非常长的列表要快一些。如果您使用add,您需要更改更少的解决方案。

jq 'group_by(.externalGroup) | map({(.[0].externalGroup):map(.groupId)}) | add'

将对象加在一起会将它们的内容组合在一起。我用 250,000 个元素的列表进行了测试,它比from_entries. 鉴于它也更短,而且在我看来也同样清晰,我认为它值得考虑。

于 2021-08-05T22:35:47.183 回答
0
  1. 生成 yaml 的一个值得考虑的替代方案gojq是 jq 的 Go 实现,例如
   gojq --yaml-output '
     group_by(.externalGroup) 
    | map({(.[0].externalGroup):map(.groupId)}) | add'
  1. 为了避免 的开销map,您可以使用以下面向add对象或数组以及数字的通用面向流:
    gojq --yaml-output '
      def add(s): reduce s as $x (null; . + $x);
      add( group_by(.externalGroup)[] 
           | {(.[0].externalGroup):map(.groupId)})'
于 2021-08-06T02:18:03.090 回答