我在使用jq组合多个对象时遇到问题。在这种情况下,MY_OBJECTS是一个json对象流,每个对象都有一个密钥。我将它们组合成一个数组,如下所示:
$ echo ${MY_OBJECTS} | jq -s '.'
[
{
"Name1": [
{
"Item1": "Val1",
"Item2": "Val2"
}
]
},
{
"Name1": [
{
"Item1": "Val3",
"Item2": "Val4"
}
]
},
{
"Name2": [
{
"Item1": "Val5",
"Item2": "Val6"
}
]
},
{
"Name2": [
{
"Item1": "Val7",
"Item2": "Val8"
}
]
}
]
我想将这些组合成一个对象,以便将一个名称下的所有Item对象合并为一个数组。基本上,我想产生以下输出:
$ echo ${MY_OBJECTS} | jq -s <SOME_COMMAND>
{
"Name1": [
{
"Item1": "Val1",
"Item2": "Val2"
},
{
"Item1": "Val3",
"Item2": "Val4"
}
],
"Name2": [
{
"Item1": "Val5",
"Item2": "Val6"
},
{
"Item1": "Val7",
"Item2": "Val8"
}
]
}
我原本期望echo ${MY_OBJECT} | jq -s add
这样做,但是这会用下面的一个覆盖每个对象,而不是添加数组,以便它们都在一个数组中(就像添加对象而不是数组一样) 。换句话说,条目看起来像这样:
"Name1": [
{
"Item1": "Val3",
"Item2": "Val4"
}
]
虽然我希望它们看起来像这样:
"Name1": [
{
"Item1": "Val1",
"Item2": "Val2"
},
{
"Item1": "Val3",
"Item2": "Val4"
}
]
任何建议都将不胜感激!
答案 0 :(得分:1)
您需要按键对对象进行分组。如果将对象映射为条目,则可以访问键。然后使用该组,构建结果对象。
您可以使用此过滤器:
map(to_entries | add)
| group_by(.key)
| map({ (.[0].key): map(.value) | add })
答案 1 :(得分:0)
group_by/1
的实现需要排序,因此这里有一种替代方法,它使用一般无用的过滤器addvalues
,不需要任何排序。请注意,对输入数组中的对象的唯一要求是每个键的值必须与add
兼容。
# Given an array of objects, combine keys using add/0.
# This implementation does not depend on sorting.
def addvalues:
reduce .[] as $o
( {}; reduce ($o|keys[]) as $key
( .; . + {($key): (.[$key] + $o[$key])} ));
addvalues
答案 2 :(得分:0)
这是一个类似于peak addvalues 解决方案的版本,为了清晰起见,缩进并注释了一下。它使用+ =来组合数组
reduce .[] as $i ( # $i: {"Name1":[{"Item1":"Val1","Item2":"Val2"}]}
{} #
; reduce ($i|keys[]) as $k ( # $k: "Name1"
. #
; .[$k] += $i[$k] # $i[$k]: [{"Item1":"Val1","Item2":"Val2"}]
)
)