问题描述
以下脚本是我导入 CSV 文件、尝试编辑其中一个值、然后检查该值的示例。
$Animal_Farm = Import-CSV "Test.csv"
Echo "The Data"
$Animal_Farm
Echo "`n`n`n"
Echo "Dog's Status"
$Animal_Farm.Status[1]
Echo "`n`n`n"
Echo "Updating Dog's Status to Employed"
$Animal_Farm.Status[1] = "Employed"
Echo "`n`n`n"
Echo "Dog's Status"
$Animal_Farm.Status[1]
这是输出,数据不变,Dog的状态还是Redundant。
The Data
Animal Ocupation Status
------ --------- ------
Cat Construction Employed
Dog Professional Redundant
Rat GP Employed
Dog's Status
Redundant
Updating Dog's Status to Employed
Dog's Status
Redundant
如何编辑导入的数据?我的计划是将修改后的数据输入到一个 JSON 文件中。
Animal,Ocupation,Status
Cat,Construction,Employed
Dog,Professional,Redundant
Rat,GP,Employed
解决方法
$Animal_Farm
包含一组对象,每个对象都有一个 Status
属性。
当您要求 PowerShell 解析 $Animal_Farm.Status
时,PowerShell 会说“嗯,$Animal_Farm
数组没有 Status
属性,让我从 {{1} }} 数组中每个项目的属性值”,这是您最终使用 Status
索引的内容。
要处理原始数组中基础项之一的属性,请直接在 $Animal_Farm.Status[1]
上使用索引运算符:
$Animal_Farm
,
用概念信息补充 Mathias R. Jessen's helpful answer:
正如 Mathias 所说,访问属性(.Status
)在对象的集合(数组)({{1 }}) 自动以数组[1]返回集合的元素的属性值(假设集合本身没有属性使用此名称,在这种情况下,后者优先)。
此功能也适用于方法,称为成员枚举,详细说明this answer 中的详细信息。
成员枚举不支持分配给属性,但是:
如果您在尝试为所有动物设置状态属性时尝试了类似 $Animal_Farm
之类的东西,您会得到有点令人惊讶的error,说明集合 $Animal_Farm.Status = 'Employed'
没有 $Animal_Farm
属性。
- 尽管出现了令人惊讶的错误消息(技术上是正确的),但无法分配一个(根据定义统一)值给给定的集合中所有单个元素的属性是设计的。
- 相比之下,通过成员枚举调用变异的方法 - 如果可用 - 是可能的。
- 有关详细信息,请参阅 this answer 和 GitHub issue #5271。
如果您尝试通过索引 (.Status
) 将属性值分配到使用成员枚举 ([...]
) 获得的值数组中,例如$Animal_Farm.Status
,该分配被悄悄忽略。
-
原因是
$Animal_Farm.Status[1] = "Employed"
返回一组属性值,这些属性不再连接到它们来自的对象,而当你技术上可以通过分配给它的元素来修改这个数组,修改后的数组在赋值语句之后被简单地丢弃,因为它没有在任何地方被捕获。
简而言之:您错误地修改了临时数组。 -
相比之下,将索引应用于集合本身(
$Animal_Farm.Status
返回存储在集合中的第二个对象)返回一个对象引用然后您可以有效修改其$Animal_Farm[1]
属性 (.Status
)
简化示例:
$Animal_Farm[1].Status = "Employed"
[1] 从技术上讲,只有当输入集合有两个或多个元素时,才会返回一个数组值;对于 single-element 集合,该元素的属性值按原样返回。换句话说:成员枚举的行为类似于 PowerShell 管道;有关相关陷阱的示例,请参阅 this answer 和 this answer,有关这种可能令人惊讶的行为的讨论,请参阅 GitHub issue #6802。