简体   繁体   English

使用 Powershell 合并/添加 2 个 JSON 文件

[英]Merging / Adding 2 JSON File together using Powershell

I want to combine following 2 JSON files below:我想在下面合并以下 2 个 JSON 文件:

This is the first JSON File which is the original JSON file这是第一个 JSON 文件,它是原始 JSON 文件

{
    "toolcache": [
        {
            "name": "Python",
            "platform" : "linux",
            "platform_version": "22.04",
            "versions": [
                "3.7.*"
            ]
        }
    ],
    "android": {
        "ndk": {
            "default": "23",
            "versions": [
                "21", "23", "24"
            ]
        }
    },
    "powershellModules": [
        {"name": "Pester"},
        {"name": "PSScriptAnalyzer"}
    ],
    "docker": {
        "images": [
            "alpine:3.14",
            "alpine:3.15",
            "buildpack-deps:buster",
            "buildpack-deps:bullseye",
            "debian:10",
            "debian:11",
            "moby/buildkit:latest",
            "node:14",
            "node:16",
            "node:14-alpine",
            "node:16-alpine"
        ]
    },
    "postgresql": {
        "version": "14"
    }
}

This is the second JSON File which we can update and we expect it to merge / add to the original first JSON File这是我们可以更新的第二个 JSON 文件,我们希望它合并/添加到原始的第一个 JSON 文件

{
    "toolcache": [
        {
            "name": "node",
            "platform" : "linux",
            "versions": [
                "16.*"
            ]
        }
    ],
    "android": {
        "cmdline-tools": "latest",
        "platform_min_version": "27",
        "build_tools_min_version": "27.0.0",
        "extra_list": [
            "android;m2repository",
            "google;m2repository",
            "google;google_play_services"
        ],
        "addon_list": [
        ],
        "additional_tools": [
            "cmake;3.10.2.4988404",
            "cmake;3.18.1"
        ]
    },
    "powershellModules": [
        {"name": "MarkdownPS"},
        {"name": "Microsoft.Graph"}
    ],
    "docker": {
        "images": [
            "ubuntu:18.04",
            "ubuntu:20.04",
            "ubuntu:22.04"
        ]
    }
} 

Here is the expected result:这是预期的结果:

{
    "toolcache": [
        {
            "name": "Python",
            "url" : "https://raw.githubusercontent.com/actions/python-versions/main/versions-manifest.json",
            "platform" : "linux",
            "platform_version": "22.04",
            "arch": "x64",
            "versions": [
                "3.7.*",
                "3.8.*",
                "3.9.*",
                "3.10.*"
            ]
        },
        {
            "name": "node",
            "platform" : "linux",
            "versions": [
                "16.*"
            ]
        }
    ],
    "android": {
        "cmdline-tools": "latest",
        "platform_min_version": "27",
        "build_tools_min_version": "27.0.0",
        "extra_list": [
            "android;m2repository",
            "google;m2repository",
            "google;google_play_services"
        ],
        "addon_list": [
        ],
        "additional_tools": [
            "cmake;3.10.2.4988404",
            "cmake;3.18.1"
        ],
        "ndk": {
            "default": "23",
            "versions": [
                "21", "23", "24"
            ]
        }
    },
    "powershellModules": [
        {"name": "Pester"},
        {"name": "PSScriptAnalyzer"},
        {"name": "MarkdownPS"},
        {"name": "Microsoft.Graph"}
    ],
    "docker": {
        "images": [
            "alpine:3.14",
            "alpine:3.15",
            "buildpack-deps:buster",
            "buildpack-deps:bullseye",
            "debian:10",
            "debian:11",
            "moby/buildkit:latest",
            "node:14",
            "node:16",
            "node:14-alpine",
            "node:16-alpine",
            "ubuntu:18.04",
            "ubuntu:20.04",
            "ubuntu:22.04"
        ]
    },
    "postgresql": {
        "version": "14"
    }
} 

I am not too sure if it is possible to add both JSON File together as I've only seen ways to merge while overwriting the existing JSON File.我不太确定是否可以将两个 JSON 文件一起添加,因为我只看到了在覆盖现有 JSON 文件时合并的方法。 I have also tried Join Object and @($source; $extend) but it was not that simple as it would just create a duplicate.我也尝试过加入 Object 和 @($source; $extend) 但这并不是那么简单,因为它只会创建一个副本。

I am try to experiment with Add-Member but I am now stuck.我正在尝试使用 Add-Member,但我现在被卡住了。 Any help would be much appreciated.任何帮助将非常感激。

It looks like you want to merge objects and append arrays .看起来您想要合并对象append arrays For this I have slightly modified the code of another answer of mine:为此,我稍微修改了我的另一个答案的代码:

function Merge-Json( $source, $extend ){
    if( $source -is [PSCustomObject] -and $extend -is [PSCustomObject] ){

        # Ordered hashtable for collecting properties
        $merged = [ordered] @{}

        # Copy $source properties or overwrite by $extend properties recursively
        foreach( $Property in $source.PSObject.Properties ){
            if( $null -eq $extend.$($Property.Name) ){
                $merged[ $Property.Name ] = $Property.Value
            }
            else {
                $merged[ $Property.Name ] = Merge-Json $Property.Value $extend.$($Property.Name)
            }
        }

        # Add $extend properties
        foreach( $Property in $extend.PSObject.Properties ){
            if( $null -eq $source.$($Property.Name) ) {
                $merged[ $Property.Name ] = $Property.Value
            }
        }

        # Convert hashtable into PSCustomObject and output
        [PSCustomObject] $merged
    }
    elseif( $source -is [Collections.IList] -and $extend -is [Collections.IList] ){

        # Output merged array, using comma operator to prevent enumeration 
        , ($source + $extend)
    }
    else{
        # Output extend object (scalar or different types)
        $extend
    }
}

Usage:用法:

$data1 = Get-Content .\data1.json -Raw | ConvertFrom-Json
$data2 = Get-Content .\data2.json -Raw | ConvertFrom-Json
Merge-Json $data1 $data2 | ConvertTo-Json -Depth 100 | Set-Content merged.json -Encoding UTF8

Output: Output:

{
  "toolcache": [
    {
      "name": "Python",
      "platform": "linux",
      "platform_version": "22.04",
      "versions": [
        "3.7.*"
      ]
    },
    {
      "name": "node",
      "platform": "linux",
      "versions": [
        "16.*"
      ]
    }
  ],
  "android": {
    "ndk": {
      "default": "23",
      "versions": [
        "21",
        "23",
        "24"
      ]
    },
    "cmdline-tools": "latest",
    "platform_min_version": "27",
    "build_tools_min_version": "27.0.0",
    "extra_list": [
      "android;m2repository",
      "google;m2repository",
      "google;google_play_services"
    ],
    "addon_list": [],
    "additional_tools": [
      "cmake;3.10.2.4988404",
      "cmake;3.18.1"
    ]
  },
  "powershellModules": [
    {
      "name": "Pester"
    },
    {
      "name": "PSScriptAnalyzer"
    },
    {
      "name": "MarkdownPS"
    },
    {
      "name": "Microsoft.Graph"
    }
  ],
  "docker": {
    "images": [
      "alpine:3.14",
      "alpine:3.15",
      "buildpack-deps:buster",
      "buildpack-deps:bullseye",
      "debian:10",
      "debian:11",
      "moby/buildkit:latest",
      "node:14",
      "node:16",
      "node:14-alpine",
      "node:16-alpine",
      "ubuntu:18.04",
      "ubuntu:20.04",
      "ubuntu:22.04"
    ]
  },
  "postgresql": {
    "version": "14"
  }
}

The output slightly differs from your expected output, but it looks like these are just minor mistakes on your side. output 与您预期的 output 略有不同,但看起来这些只是您这边的小错误。 Also, my function puts android.ndk at the beginning, as it is from the first file.另外,我的 function 将android.ndk放在开头,因为它来自第一个文件。 This shouldn't matter, because the JSON standard doesn't specify the ordering of properties to be significant.这无关紧要,因为 JSON 标准并未指定重要的属性顺序。

For detailed explanation of the code, see the answer linked at the top.有关代码的详细说明,请参阅顶部链接的答案。 The only difference here is the elseif branch, which appends arrays.这里唯一的区别是elseif分支,它附加了 arrays。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM