如何有条件地进行递归合并?

时间:2019-11-20 22:33:35

标签: json jq

我想有条件地进行递归合并。也就是说,如果第二个对象中存在键,则我想用它来覆盖第一个对象中的值。例如,这符合我的要求:

$ echo '{"a":"value"}{"bar": {"a":"override"}}' | jq -sS '.[0] * if (.[1].foo|length) > 0 then .[1].foo else {} end'
{
  "a": "value"
}
$ echo '{"a":"value"}{"foo": {"a":"override"}}' | jq -sS '.[0] * if (.[1].foo|length) > 0 then .[1].foo else {} end'
{
  "a": "override"
}

在第一个示例中,第二个对象不包含“ foo”键,因此不会发生覆盖。在第二个示例中,第二个对象确实包含“ foo”,因此更改了值。 (在我的实际使用中,我在输入上总是有3个对象,有时有第4个对象,它可能会覆盖一些先前的值。)

尽管上述方法有效,但看起来却很丑陋。有没有更清洁的方法可以做到这一点?我想象像jq -sS '.[0] * (.[1].foo ? .[1].foo : {})之类的东西。

1 个答案:

答案 0 :(得分:2)

通过在命令行上指定-n标志,就可以达到目的:

reduce inputs as $in (input; . * ($in.foo // {}))

jqplay demo