将2个JSON对象与jq合并

将2个JSON对象与jq合并,json,bash,merge,key,jq,Json,Bash,Merge,Key,Jq,我在两个变量V1和V2中有两个json对象 V1是 V2是 我想用V2中的值覆盖V1的值。我想生成一个新的JSON,如下所示: 预期的 { "Parameters": { "a": "new-value-of-a", "b": "value-of-b" } } 我尝试了以下方法: ( echo '{ "Parameters": { &quo

我在两个变量V1和V2中有两个json对象

V1是

V2是

我想用V2中的值覆盖V1的值。我想生成一个新的JSON,如下所示:

预期的

{
   "Parameters": {
      "a": "new-value-of-a",
      "b": "value-of-b"
   }
}
我尝试了以下方法:

(
echo '{ "Parameters": { "a": "value-of-a", "b": "value-of-b" } }'\
'{ "Parameters": { "a": "new-value-of-a", "c": "value-of-c" } }'\
| jq --slurp 'reduce .[] as $item ({}; . * $item)'
)

但这会产生

实际值

{
   "Parameters": {
      "a": "new-value-of-a",
      "b": "value-of-b",
      "c": "value-of-c"
   }
}

问题是,我不希望V2中不存在于V1中的节点出现在结果中。有人能帮我吗?

如果<代码>$。参数对象和您的示例一样简单

jq\
--argjson a'{“参数”:{“a”:“value-of-a”,“b”:“value-of-b”}\
--argjson b'{“参数”:{“a”:“new-value-of-a”,“c”:“value-of-c”}\
-不
$a |.参数|键|未排序为$whitelist
|$b |.Parameters |带有_项(在($whitelist[])中选择(.key |)作为$update
|$a |.Parameters+=$update'

如果您有两个文件,您可以(例如)使用
input
两次,而不是
--argjson

以下是一个既简单又高效的解决方案:

jq -n '
   input.Parameters as $dict
   | input
   | .Parameters |= reduce keys_unsorted[] as $k (.;
       if ($dict|has($k)) then .[$k] = $dict[$k] else . end)
' v2.json v1.json 
如果这两个值是shell变量,则可以使用
--argjson
或简单地回显它们:

echo "$v2" "$v1" | jq -n '...'

提供这两个值还有其他方法,但通常最好避免使用-s命令行选项。

这里有一个概念简单且可扩展性好的无缩减解决方案:

jq -n '
   # Emit the object with key-value pairs of $o2 
   # for keys that appear in both . and $o2
   def commonKeys($o2):
     keys_unsorted as $k1
     | ($o2|keys_unsorted) as $k2
     | [($k1 - ($k1-$k2))[] | {(.): $o2[.]}] | add
   ;
   input.Parameters as $dict
   | input
   | .Parameters |= (. + commonKeys($dict))

' v2.json v1.json 

安德烈,非常感谢你抽出时间回答我的问题!谢谢你!我是如此的遥远。。。我看到,对于静态值,它是有效的。但是,一旦我更改为--slurpfile,就会出现以下错误:无法使用字符串“Parameters”索引数组。为了使用--slurpfile,应该如何更改它?我刚刚将脚本更改为使用--argfile而不是--slurpfile,它工作得很好。安德烈,再次感谢你的帮助!你救了我一天<代码>输入尝试读取一个JSON值,而不进行任何回溯。参见jq手册
echo "$v2" "$v1" | jq -n '...'
jq -n '
   # Emit the object with key-value pairs of $o2 
   # for keys that appear in both . and $o2
   def commonKeys($o2):
     keys_unsorted as $k1
     | ($o2|keys_unsorted) as $k2
     | [($k1 - ($k1-$k2))[] | {(.): $o2[.]}] | add
   ;
   input.Parameters as $dict
   | input
   | .Parameters |= (. + commonKeys($dict))

' v2.json v1.json