下面的脚本是我导入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的状态仍然是冗余。
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文件中。
这是CSV文件内容
Animal,Ocupation,Status
Cat,Construction,Employed
Dog,Professional,Redundant
Rat,GP,Employed
$Animal_Farm
包含一个对象数组,每个对象都有一个Status
属性。
当您要求PowerShell解析$Animal_Farm.Status
时,PowerShell将转到";嗯,$Animal_Farm
数组没有Status
属性,让我根据数组中每个项的Status
属性值创建一个新数组",这就是你最终用CCD_ 7索引的内容。
要处理原始数组中某个底层项的属性,请直接在$Animal_Farm
上使用索引运算符:
$Animal_Farm[1].Status
用概念信息补充Mathias R.Jessen的有用答案:
正如Mathias所说,访问对象($Animal_Farm
(的集合(数组(上的属性(.Status
(会自动返回数组[1]中该集合的元素的属性值(假设集合本身没有此名称的属性,在这种情况下,后者优先(。
此功能也适用于方法,称为成员访问枚举,在本答案中有更详细的解释。
成员访问枚举不支持将分配给属性,但是:
如果您在尝试为所有动物设置状态属性时尝试了类似$Animal_Farm.Status = 'Employed'
的操作,则会出现有点令人惊讶的错误,说明集合$Animal_Farm
没有.Status
属性。
- 尽管出现了令人惊讶的错误消息(从技术上讲是正确的(,但无法将(根据定义统一(值分配给集合中所有单个元素的给定属性,这是设计上的
- 相比之下,通过成员访问枚举(如果可用(调用一个可变的方法是可能的
- 有关更多信息,请参阅此答案和GitHub第5271期
如果您试图通过索引([...]
(将属性值分配到通过成员访问枚举($Animal_Farm.Status
((例如$Animal_Farm.Status[1] = "Employed"
(获得的值数组中,则将悄悄忽略该分配。
-
原因是
$Animal_Farm.Status
返回一个属性值的数组,这些值不再与它们来自的对象连接,虽然从技术上讲,您可以通过向其元素赋值来修改此数组,但修改后的数组在赋值语句后会被丢弃,因为它不会在任何地方捕获
简而言之:您错误地修改了临时数组。 -
相反,将索引应用于集合本身(
$Animal_Farm[1]
返回存储在集合中的第二个对象(会返回的对象引用,然后可以有效地修改其.Status
属性($Animal_Farm[1].Status = "Employed"
(
简化示例:
# Create a 2-element sample array.
$animals = [pscustomobject] @{ Animal = 'Cat'; Status = 'Employed' },
[pscustomobject] @{ Animal = 'Dog'; Status = 'Redundant' }
# Trying to set the status of ALL animals via member-access enumeration
# CAUSES AN ERROR, because it isn't supported:
# InvalidOperation: The property 'Status' cannot be found on this object. [...]
$animals.Status = 'Employed' # !! ERROR
# Trying to set the status of ONE animal via member-access enumeration is
# QUIETLY IGNORED:
# * What is being modified is a *temporary array* of property values.
# * Therefore, $animals.Status[1] is still 'Redundant' after this statement.
$animals.Status[1] = 'Employed' # !! QUIETLY IGNORED
# OK: Avoid member-access enumeration, and index directly into the collection
# to get the animal object of interest, then set its property:
$animals[1].Status = 'Employed' # OK
[1]从技术上讲,只有当输入集合具有两个或多个元素时,才会返回值的数组;对于单个元素集合,该元素的属性值将按原样返回。换句话说:成员访问枚举的行为类似于PowerShell管道;请参阅这个答案和这个答案,了解相关陷阱的示例,以及GitHub第6802期关于这种可能令人惊讶的行为的讨论