将多个 JSON 文件读入 Powershell 对象数组,并过滤​​掉具有相同属性值的对象 [英] Read multiple JSON files into an array of Powershell objects and filter out those with the same value for a property

查看:26
本文介绍了将多个 JSON 文件读入 Powershell 对象数组,并过滤​​掉具有相同属性值的对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我第一次,如果我的问题布局有问题,请告诉我.

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

<预><代码>[{"Forename": "Jim","姓氏": "厨师","性别": "M","DOB": "12-03-1994"},{"Forename": "莎拉","姓氏": "帕克","性别": "F","DOB": "01-02-1983"},{"Forename": "艾伦","姓氏": "弗莱明","性别": "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——————————————————吉姆库克 M 12-03-1994

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

Forename Surname Gender DOB——————————————————吉姆库克 M 12-03-1994莎拉·帕克 F 01-02-1983艾伦·弗莱明 M 27-10-1989比尔普雷斯顿 M 04-07-1975海伦史密斯 F 03-12-2001

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

解决方案

问题在于,在 PowerShell 版本高达 v6.x 中,ConvertFrom-Json 输出(转换自)JSON 数组作为单个对象,而不是逐个元素,这在 PowerShell 中是典型的.

  • 注意:在 PowerShell [Core] 7.0 中,行为已更改 以与通常的元素枚举行为保持一致,并且-NoEnumerate 开关已添加为旧行为的选择.

如果(至少)它的一个元素有一个,这会导致整个数组通过Where-Object获得输出.ForeName 属性值为 Jim,感谢 成员枚举.

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

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

注意我已经替换了 Get-Content $_.FullName |带有 Get-Content -Raw $_.FullName (PSv3+) 的 Out-String,对于将文件内容作为单行多行字符串进行检索既更简洁也更高效.

It's my first time, so let me know if I'm doing something wrong with the layout of my question.

I have a lot of JSON files with filenames that follow a naming convention, i.e. file1.json, file2.json, etc. Each of which are likely to have multiple objects which look like:

[
    {
        "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"
    }
]

In Powershell, I would like to convert these JSON objects into Powershell objects and then select objects with the same value for a property, like people whose first name is "Jim".

So far I've achieved this:

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

This works when there is only one file to work with, which outputs:

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

However it fails and outputs all objects when used with multiple files, as though the Where-Object is being ignored. The result can look like this:

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

Can someone please suggest what I'm doing wrong here and how it can be fixed to get the correct result? Thanks

解决方案

The problem is that, in PowerShell versions up to v6.x, ConvertFrom-Json outputs (converted-from-)JSON arrays as single objects rather than element by element, as is otherwise typical in PowerShell.

  • Note: In PowerShell [Core] 7.0, the behavior was changed to align with the usual enumeration-of-elements behavior, and a -NoEnumerate switch was added as an opt-in to the old behavior.

This results in the entire array getting output by Where-Object if (at least) one of its elements has a .ForeName property with value Jim, thanks to member enumeration.

The workaround is to force enumeration, which in the simplest case is achieved by wrapping the command the ConvertFrom-Json call in (...):

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

Note that I've replaced Get-Content $_.FullName | Out-String with Get-Content -Raw $_.FullName (PSv3+), which is both more concise and more efficient for retrieving a file's content as a single, multi-line string.

这篇关于将多个 JSON 文件读入 Powershell 对象数组,并过滤​​掉具有相同属性值的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆