jq:如何组合重复键的数据

时间:2017-04-11 04:55:15

标签: json merge key jq

我有一个相当复杂的JSON数据结构,我设法使用jq过滤到某些键及其值。我需要将结果组合起来,因此重复键只有一个值数组 e.g。

     {
    "1.NBT.B": [
      {
        "id": 545
      },
      {
        "id": 546
       }
    ]
  },
  {
    "1.NBT.B": [
      {
        "id": 1281
      },
      {
        "id": 1077
      }
    ]
  }

会导致

 {
    "1.NBT.B": [
      {
        "id": 545
      },
      {
        "id": 546
       },
      {
        "id": 1281
      },
      {
        "id": 1077
      }
    ]
  },
...

甚至更好:

[{"1.NBT.B": [545, 546, 1281, 1077]}, ...]

我需要直接输入密钥(" 1.NBT.B"),因为这些密钥有数百个。我认为最让我困惑的是这里的对象没有被命名 - 对象之间的键不一样。

这样的东西只给了我第二组id,完成了跳过第一组:

reduce .[] as $item ({}; . + $item)

1 个答案:

答案 0 :(得分:2)

第1部分

以下jq函数以问题第一部分所设想的方式组合了一组对象。

# Given an array of objects, produce a single object with an array at
# every key, the array at each key, k, being formed from all the values at k.
def merge:
  reduce .[] as $o ({}; reduce ($o|keys)[] as $key (.; .[$key] += $o[$key] ));

将此定义与行一起使用:

merge

在一个文件中,并将示例输入修改为有效的JSON数组, 结果是:

{
  "1.NBT.B": [
    {
      "id": 545
    },
    {
      "id": 546
    },
    {
      "id": 1281
    },
    {
      "id": 1077
    }
  ]
}

第2部分

使用上面定义的merge,过滤器:

merge | with_entries( .value |= map(.id) )

产生

{
  "1.NBT.B": [
    545,
    546,
    1281,
    1077
  ]
}