powershell防止重复的对象键

时间:2016-12-09 21:48:35

标签: powershell

这是this question

的后续行动

如果我有2个json文件

file1.json

{
  "foo": {
    "honk": 42
  }
}

file2.json

{
  "foo": {
    "honk": 9000,
    "toot": 9000
  }
}

我使用ConvertFrom-Json

创建一个对象
$bar = @(Get-ChildItem . -Filter *.json -Recurse | Get-Content -Raw |ConvertFrom-Json)

Powershell将很乐意接受这两个,并覆盖foo。

foo

---
@{honk=42}
@{honk=9000; toot=9000}

$ bar.foo的内容已合并

$bar.foo

honk
----
  42
9000

如果导入重复的对象,我怎么会出错?

2 个答案:

答案 0 :(得分:2)

每个JSON文件都作为单独的对象导入,因此实际上没有任何覆盖。你只需要一个对象列表。

如果在获得具有相同顶级属性的多个对象时抛出错误,则可以按属性名称对对象进行分组,如果计数> 1则抛出错误。

$bar | Group-Object { $_.PSObject.Properties.Name } |
  Where-Object { $_.Count -gt 1 } |
  ForEach-Object { throw "Duplicate object $($_.Name)" }

答案 1 :(得分:0)

导入数组时,每个对象都是唯一的。在这个例子中,将对象保留在数组中是不理想的,因为没有办法可预测地迭代它们,因为一些对象可能包含多个键。

{
  "foo": 42
}

VS

{
  "bar": 9000,
  "buzz": 9000
}

这会在尝试遍历所有对象时引起心痛。

相反,我将所有数组项目合并为1个powershell对象。由于powershell对象基本上是哈希值,并且设计中的哈希值必须具有唯一的键,因此如果覆盖键,powershell将自动出错。

function Load-Servers {

    $allObjects = @(
        Get-ChildItem '.\servers' -Filter *.json -Recurse | Get-Content -Raw | ConvertFrom-Json
    )
    $object = New-Object PSObject
    Foreach ($o in $allObjects) {
        $o.psobject.members | ? {$_.Membertype -eq "noteproperty" } | %{$object | add-member $_.Name $_.Value }
    }

    return $object
}