【问题标题】:Merge 2 JSON objects with jq将 2 个 JSON 对象与 jq 合并
【发布时间】:2021-01-11 02:01:25
【问题描述】:

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

V1 是

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

V2 是

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

我想用 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 中的节点出现在结果中。谁能帮帮我?

【问题讨论】:

    标签: json bash merge key jq


    【解决方案1】:

    如果$.Parameter 对象像您的示例一样简单

    jq \
     --argjson a '{ "Parameters": { "a": "value-of-a", "b": "value-of-b" } }' \
     --argjson b '{ "Parameters": { "a": "new-value-of-a", "c": "value-of-c" } }' \
     -n '
       $a | .Parameters | keys_unsorted as $whitelist 
     | $b | .Parameters | with_entries( select(.key | IN($whitelist[])) ) as $update
     | $a | .Parameters += $update '
    
    

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

    【讨论】:

    • 安德烈,非常感谢您花时间回答我的问题!欣赏它!我离得很远......我看到它使用静态值。但是,一旦我更改为 --slurpfile,我就会收到以下错误:无法使用字符串“Parameters”索引数组。应该如何更改才能使用 --slurpfile ?
    • 我只是将脚本更改为使用 --argfile 而不是 --slurpfile 并且效果很好。安德烈,再次感谢您的帮助!你拯救了我的一天!
    【解决方案2】:

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

    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 命令行选项。

    【讨论】:

    【解决方案3】:

    这是一个概念上简单且可扩展性良好的无 reduce 解决方案:

    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 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-07-21
      • 1970-01-01
      • 2022-10-24
      • 2013-11-01
      • 1970-01-01
      • 2019-03-24
      • 1970-01-01
      相关资源
      最近更新 更多