【问题标题】:How do I edit the values of imported CSV variable with PowerShell如何使用 PowerShell 编辑导入的 CSV 变量的值
【发布时间】:2021-09-23 08:30:48
【问题描述】:

以下脚本是我导入 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 文件。

这是 CSV 文件的内容

Animal,Ocupation,Status
Cat,Construction,Employed
Dog,Professional,Redundant
Rat,GP,Employed

【问题讨论】:

  • $Animal_Farm.Status[1] = "Employed" 更改为 $Animal_Farm[1].Status = "Employed"

标签: powershell member-enumeration


【解决方案1】:

$Animal_Farm 包含一个对象数组,每个对象都有一个Status 属性。

当您要求 PowerShell 解析 $Animal_Farm.Status 时,PowerShell 会出现“嗯,$Animal_Farm 数组没有 Status 属性,让我根据其中每个项目的 Status 属性值创建一个新数组数组”,这是您最终使用 $Animal_Farm.Status[1] 索引的内容。

要处理原始数组中的基础项之一的属性,请直接在$Animal_Farm 上使用索引运算符:

$Animal_Farm[1].Status

【讨论】:

    【解决方案2】:

    用概念信息补充Mathias R. Jessen's helpful answer

    正如 Mathias 所说,访问属性 (.Status) 集合(数组) 对象 ($Animal_Farm) 上自动在数组[1] 中返回集合的元素 的属性值(假设集合本身没有同名的属性,在这种情况下,后者优先)。

    此功能也适用于方法,称为成员枚举,将在更多详情见this answer

    成员枚举支持分配到属性,但是:

    如果您在尝试为所有动物设置状态属性时尝试类似$Animal_Farm.Status = 'Employed',您会得到有点令人惊讶的错误,说明集合$Animal_Farm 没有.Status 属性。

    • 尽管有令人惊讶的错误消息(技术上正确),但无法分配(根据定义统一)给定的值集合的所有单个元素的属性设计
    • 相比之下,通过成员枚举调用变异方法 - 如果可用 - 可能的。
    • 有关详细信息,请参阅 this answerGitHub issue #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 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 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 enumeration, and index directly into the collection
    #     to get the animal object of interest, then set its property:
    $animals[1].Status = 'Employed' # OK
    

    [1] 从技术上讲,只有当输入集合具有 两个或更多 元素时,才会返回 数组 值;对于 single-element 集合,该元素的属性值按原样返回。换句话说:成员枚举的行为类似于 PowerShell 管道;有关相关陷阱的示例,请参阅 this answerthis answer,有关此可能令人惊讶的行为的讨论,请参阅 GitHub issue #6802

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-08-30
      • 2014-01-15
      • 2020-08-12
      • 2016-12-30
      • 1970-01-01
      • 1970-01-01
      • 2018-07-25
      • 1970-01-01
      相关资源
      最近更新 更多