将多个 JSON 文件读入 Powershell 对象数组,并过滤掉具有相同属性值的对象 [英] Read multiple JSON files into an array of Powershell objects and filter out those with the same value for a property
问题描述
这是我第一次,如果我的问题布局有问题,请告诉我.
我有很多 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
获得输出.ForeNameJim
,感谢 成员枚举.
解决方法是强制枚举,在最简单的情况下,这是通过将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屋!