I have the following inputs - 2 json files one is the base one and the second contains the same properties but the different values, I'd like to merge that objects.
For example:
{
a:{
b:"asda"
}
c: "asdasd"
}
And the second file:
{
a:{
b:"d"
}
}
And the result should be like this:
{a:{b:"d"},c:"asdasd"}
Is that is possible with powershell?
Join (Join-Object) is not a built-in CmdLet
This is an extension of @Mark's answer which also recurses through child objects.
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
(see update below)$Json1 | Join $Json2 -Merge {$Right.$_} | ConvertTo-Json
($Json1 ConvertFrom-Json) | Merge ($Json2 ConvertFrom-Json) | ConvertTo-Json
Result:
{
"c": "asdasd",
"a": {
"b": "d"
}
}
You might consider not to overwrite the left value:
($Json1 ConvertFrom-Json) | Join ($Json2 ConvertFrom-Json) | ConvertTo-Json
In that case the result will be:
{
"c": "asdasd",
"a": [
{
"b": "asda"
},
{
"b": "d"
}
]
}
For details see: https://stackoverflow.com/a/45483110/1701026
Update 2019-11-16
The -Merge
parameter has been depleted and divided over the -Discern
and -Property
parameters (sorry for the breaking change). The good news is that the default parameter settings for an object merge are accommodated in a proxy command named Merge-Object
(alias Merge
) which simplifies the concerned syntax to just: $Object1 | Merge $Object2
. For details, see readme or embedded help.
If you know the names of the elements (per your example above), you could do it explicitly like this:
$Json1 ='{
a: {
b:"asda"
},
c: "asdasd"
}
' | ConvertFrom-Json
$Json2 = '{
a:{
b:"d"
}
}
' | ConvertFrom-Json
$Json1.a = $Json2.a
Result:
$Json1 | ConvertTo-Json
{
"a": {
"b": "d"
},
"c": "asdasd"
}
If you're looking for something that will merge the two without knowing the explicit key name, you could do something like the following. This will essentially overwrite any properties in the first Json with those from the second Json, where they are duplicated at the first level (it won't seek matches in the nested properties and again this is an overwrite not a merge):
$Json2.psobject.Properties | ForEach-Object {
$Json1 | Add-Member -MemberType $_.MemberType -Name $_.Name -Value $_.Value -Force
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With