这是关于命令行json处理器jq的问题。关于javascript或jQuery或名称中带有js和qs的其他任何内容不是 :)>
我输入的数据如下:
VBoxHeadless
我想要这样的输出:
{ "id": "person1", "name": "wilma", "age": "quite old"}
{ "id": "person2", "name": "fred"}
{ "id": "person1", "name": "betty", "x": "extra"}
我尝试了各种事情!
例如
{
"person1": { "name": "betty", "age": "quite old", "x": "extra" },
"person2": { "name": "fred" }
}
给予
jq -s '.[] | { (.id) : . }' <data
除了输出一个对象流而不是一个对象流之外,它在那里。我需要将所有这些对象合并在一起。
我也尝试过使用{ "person1": { "id": "person1", "name": "wilma", "age": "quite old" }}
{ "person2": { "id": "person2", "name": "fred" }}
{ "person1": { "id": "person1", "name": "betty", "x": "extra" }}
合并每个项目,但仍然会产生一个流。 https://jqplay.org/s/lh6QUQ0DO4
答案 0 :(得分:1)
您可以按以下方式调整尝试:
jq -s 'map({ (.id) : . }) | add' <data
但是,将inputs
和reduce
与-n命令行选项一起使用而不是-s会更有效。
当然,使用这种方法会带来碰撞的风险。
您可能还想添加del(.id)
答案 1 :(得分:1)
啊!我懂了!或者我有一个解决方案-如果有更好的方法,请发表。
jq -s '[group_by(.id)[]| add | { (.id) : . } ]|add' <data
https://jqplay.org/s/BfAdRBZUMW
group_by
通过.id
值对输入进行分组,并生成一个数组数组-内部数组是与id匹配的值。
对于每个组,将内部数组传递到add
,由于内部数组中的对象是对象,因此它们会合并。
剩下2个项目数组。我们将其提供给对象构造器,该构造器将id
作为键,将整个项目作为值。仍然留下了一系列物品。
外部[]
(从模式开始处开始)说,将所有内容都接受并将其提供给add
(再次),它将合并在(3)中创建的最终对象。
它可以工作,但是可能会有更干净的方法。
这很丑陋,但产生的结果相同,在9MB的数据集上,速度提高了约24%。
jq -s 'reduce [.[]|{ (.id) : . }][] as $item ({}; . * $item )' <data
这使用reduce <list> as <$var> (<initiation>; <iteration>)
(从一个空对象{}
开始,并使用合并运算符*
(从传入项目.
开始)来创建输出。令我惊讶的是它的速度更快,但是我知道group_by
可以完成排序,所以我认为这是额外的时间成本。