将多个JSON文件读入Powershell对象数组,并过滤 掉属性值相同的文件

问题描述 投票:1回答:1

这是我的第一次,所以如果我对问题的布局做错了,请告诉我。

我有很多JSON文件,其文件名遵循命名约定,即file1.json,file2.json等。每个文件都可能有多个对象,如下所示:

[
    {
        "Forename":  "Jim",
        "Surname":  "Cook",
        "Gender":  "M",
        "DOB":  "12-03-1994"
    },
    {
        "Forename":  "Sarah",
        "Surname":  "Parker",
        "Gender":  "F",
        "DOB":  "01-02-1983"
    },
    {
        "Forename":  "Alan",
        "Surname":  "Flemming",
        "Gender":  "M",
        "DOB":  "27-10-1989"
    }
]

在Powershell中,我想将这些JSON对象转换为Powershell对象,然后为属性选择具有相同值的对象,例如名字为“Jim”的人。

到目前为止我已经实现了这个目标:

@(Get-ChildItem "file*.json" | %{Get-Content $_.FullName | Out-String | ConvertFrom-Json}) | Where-Object {$_.Forename -eq "Jim"}

当只有一个文件可以使用时,这可以工作,输出:

Forename Surname Gender DOB
-------- ------- ------ ---
Jim      Cook    M      12-03-1994

但是,当与多个文件一起使用时,它会失败并输出所有对象,就像忽略Where-Object一样。结果可能如下所示:

Forename Surname  Gender DOB
-------- -------  ------ ---
Jim      Cook     M      12-03-1994
Sarah    Parker   F      01-02-1983
Alan     Flemming M      27-10-1989
Bill     Preston  M      04-07-1975
Helen    Smith    F      03-12-2001

有人可以建议我在这里做错了什么以及如何修复以获得正确的结果?谢谢

arrays json powershell enumeration
1个回答
2
投票

问题是ConvertFrom-Json输出(转换自)JSON数组作为单个对象而不是逐个元素,这在PowerShell中是典型的。

这个有问题的行为是this GitHub issue的主题。

这导致整个数组由Where-Object输出,如果(至少)其中一个元素具有值为.ForeNameJim属性,这要归功于member enumeration

解决方法是强制枚举,在最简单的情况下,通过在ConvertFrom-Json中包装(...)调用命令来实现:

Get-ChildItem file*.json | ForEach-Object {
  (Get-Content -Raw $_.FullName | ConvertFrom-Json)
} | Where-Object { $_.Forename -eq "Jim" }

请注意,我已经用Get-Content $_.FullName | Out-String(PSv3 +)替换了Get-Content -Raw $_.FullName,这对于将文件内容检索为单个多行字符串更加简洁和高效。

© www.soinside.com 2019 - 2024. All rights reserved.