【问题标题】:Merge two json objects合并两个 json 对象
【发布时间】:2018-01-14 22:29:04
【问题描述】:

我有以下输入 - 2 个 json 文件,一个是基础文件,第二个包含相同的属性但不同的值,我想合并这些对象。

例如:

{
  a:{
    b:"asda"
  }
  c: "asdasd"
}

还有第二个文件:

{
  a:{
   b:"d"
  }
}

结果应该是这样的:

{a:{b:"d"},c:"asdasd"}

powershell可以做到吗?

【问题讨论】:

  • 仅供参考,我必须在第一个 JSON a: 元素右括号后添加一个逗号以使其有效 JSON。

标签: json powershell


【解决方案1】:

$Json1 | Join $Json2 -Merge {$Right.$_} | ConvertTo-Json (见下方更新)

($Json1 ConvertFrom-Json) | Merge ($Json2 ConvertFrom-Json) | ConvertTo-Json

结果:

{
    "c":  "asdasd",
    "a":  {
              "b":  "d"
          }
}

你可以考虑不覆盖左边的值:

($Json1 ConvertFrom-Json) | Join ($Json2 ConvertFrom-Json) | ConvertTo-Json

在这种情况下,结果将是:

{
    "c":  "asdasd",
    "a":  [
              {
                  "b":  "asda"
              },
              {
                  "b":  "d"
              }
          ]
}

详情见:https://stackoverflow.com/a/45483110/1701026


2019 年 11 月 16 日更新
-Merge 参数已被耗尽并划分为 -Discern-Property 参数(对于重大更改感到抱歉)。好消息是对象合并的默认参数设置包含在名为Merge-Object(别名Merge)的代理命令中,该命令将相关语法简化为:$Object1 | Merge $Object2。有关详细信息,请参阅readme 或嵌入式帮助。

【讨论】:

  • 在 ps 7.0 上对我不起作用 :_(。我结束了使用 @waxingsatirical
【解决方案2】:

Join(Join-Object) 不是内置的 CmdLet

这是@Mark 答案的扩展,它也通过子对象递归。

function merge ($target, $source) {
    $source.psobject.Properties | % {
        if ($_.TypeNameOfValue -eq 'System.Management.Automation.PSCustomObject' -and $target."$($_.Name)" ) {
            merge $target."$($_.Name)" $_.Value
        }
        else {
            $target | Add-Member -MemberType $_.MemberType -Name $_.Name -Value $_.Value -Force
        }
    }
}

merge $Json1 $Json2

$Json1

【讨论】:

    【解决方案3】:

    如果您知道元素的名称(根据上面的示例),您可以像这样明确地这样做:

    $Json1 ='{
      a: {
        b:"asda"
      },
      c: "asdasd"
    }
    ' | ConvertFrom-Json
    
    $Json2 = '{
      a:{
       b:"d"
      }
    }
    ' | ConvertFrom-Json
    
    
    $Json1.a = $Json2.a
    

    结果:

    $Json1 | ConvertTo-Json
    
    {
        "a":  {
                  "b":  "d"
              },
        "c":  "asdasd"
    }
    

    如果您正在寻找在不知道显式键名的情况下将两者合并的东西,您可以执行以下操作。这实际上将用第二个 Json 中的属性覆盖第一个 Json 中的任何属性,它们在第一级重复(它不会在嵌套属性中寻找匹配项,这又是覆盖而不是合并):

    $Json2.psobject.Properties | ForEach-Object {
        $Json1 | Add-Member -MemberType $_.MemberType -Name $_.Name -Value $_.Value -Force
    }
    

    【讨论】:

    • 是的,我正在寻找基于匹配键名的解决方案
    • 我已经用另一个选项修改了我的答案,用 Json2 中的属性覆盖 Json1 的属性,但请记住,这仍然不是真正的合并,但可能会让你更接近一点。
    猜你喜欢
    • 2019-12-17
    • 1970-01-01
    • 2021-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-27
    相关资源
    最近更新 更多