我有一个JSON对象数组,我想为每个对象添加一个特定的属性。
例如,数组如下:
[
{
"Average": 1.3085,
"ExtendedStatistics": {
},
"Maximum": 0,
"Minimum": 0,
"SampleCount": 0,
"Sum": 0,
"Timestamp": "\/Date(1496972280000)\/",
"Unit": {
"Value": "Percent"
}
},
{
"Average": 1.4324999999999999,
"ExtendedStatistics": {
},
"Maximum": 0,
"Minimum": 0,
"SampleCount": 0,
"Sum": 0,
"Timestamp": "\/Date(1496944680000)\/",
"Unit": {
"Value": "Percent"
}
}
]
我想补充一下“来源”:“CPU”的所有对象。我该怎么做呢?我是PowerShell的新手,还没有完成这个任务。
2条答案
按热度按时间bq8i3lrv1#
您可以执行以下操作:
这假设你的JSON输入是在一个名为
$JSON
的变量中,你需要用你访问JSON内容的方式来替换它(例如Get-Content yourfile.json
)。有了JSON之后,我们使用
ConvertFrom-JSON
将其转换为PowerShell对象。然后,我们使用管道将其发送到
ForEach-Object
循环,该循环使用Add-Member
cmdlet将属性添加到集合中的每个项目(当前项目由$_
表示),名为“Source”,值为“CPU”。根据mklement 0的注解,需要使用-PassThru
开关将结果发送回管道。然后,我们将该输出通过管道传输到ConvertTo-JSON以将其转换回来。
snvhrwxg2#
Mark Wragg's helpful answer运行良好,但您可能想知道**为什么
Add-Member
cmdlet不能通过管道 * 直接 ,而不是需要一个封闭的ForEach-Object
调用*:可以说,以下 * 应该 * 工作,但在 Windows PowerShell 不:
其思想是
Add-Member
直接使用管道输入,并在修改每个输入对象后输出它,这要归功于-PassThru
(默认情况下Add-Member
不产生输出)。它不起作用的原因是当Windows PowerShell的
ConvertFrom-Json
输出 * 数组 * 时,它将其 * 作为单个对象 * 输出,而不是像人们所期望的那样通过管道逐个发送其元素。-NoEnumerate
开关作为旧行为的选择。有关导致此更改的讨论,请参见GitHub issue #3424。解决方法:
(...)
,强制枚举数组:请注意,通常,使用
(...)
强制将命令的整个输出收集到内存中的数组中是很方便的,但对于大的输出集可能会有问题。然而,正如PetSerAl所指出的,在这种情况下,它是好的,因为ConvertFrom-Json
本身在内存中构建了整个输出数组。Write-Output -NoEnumerate
(Windows PowerShell)/的传递调用Write-Output
(PowerShell Core),其唯一目的是强制枚举数组元素:可选阅读:关于
Write-Output
:由于一个 bug,
Write-Output
* 总是 * 枚举本身就是集合的单个对象,即使您添加了-NoEnumerate
。矛盾的是,在这种情况下,
-NoEnumerate
实际上是 * 需要的 *-即使我们 * 确实 * 想要枚举!- 以防止Write-Output
应用枚举 * 两次 *:一次(不变地)到输入数组,再次到各个数组元素(再次感谢PetSerAl);例如:PowerShell(Core)v6.2.3+:
上面的问题已经被修复了-参见GitHub issue #5955-这意味着-明智地-如果你确实想让
Write-Output
枚举本身就是集合的管道对象(枚举不再递归1级),你 * 不能 * 使用-NoEnumerate
。