powershell - Import-CSV:将行(成员)添加到 foreach 循环中的结果对象

标签 powershell import-csv psobject pscustomobject

我正在尝试使用 Powershell 中导入的 CSV 数据实现以下目标:

CSV 具有以下结构:

| FirstName | LastName | Tier |
| --------- | -------  | ---- |
|  George   | Smith    |  0   |
|  John     | Fritz    |  1   |
|  Thomas   | Adams    |  1   |
|  Manuel   | Evans    |  0   |

我按如下方式导入 CSV 数据:

$csv = Import-Csv csvfile.csv

现在问题来了。我正在尝试向对象添加更多行

$csv

如果用户属于第 0 层,则应将同一用户添加到第 1 层的对象。

生成的 $csv 对象应如下所示:

| FirstName | LastName | Tier |
| --------- | -------  | ---- |
|  George   | Smith    |  0   |
|  John     | Fritz    |  1   |
|  Thomas   | Adams    |  1   |
|  Manuel   | Evans    |  0   |
|  George   | Smith    |  1   |
|  Manuel   | Evans    |  1   |

新的第 1 层行在对象中的放置顺序并不重要。它们应该位于包含所有原始数据的对象中的某个位置。我也不需要任何 CSV 文件中生成的第 1 层行。我只需要这些新行(成员)成为 $csv 对象的一部分,所有其他数据保持不变,这样我就可以使用 foreach 循环迭代同一对象中的原始数据和新数据。

到目前为止我尝试过但没有取得积极结果:

$csv = Import-Csv csvfile.csv

foreach ($User in $csv){ 
    $tier = $User.Tier -replace '\s',''
    if($tier -eq '0'){  
    $csv+= @{FirstName= $User.FirstName; LastName=$User.LastName; Tier='1'}
    }
}

再次尝试但没有取得积极结果:

$csv = Import-Csv csvfile.csv

foreach ($User in $csv){ 
    $tier = $User.Tier -replace '\s',''
    if($tier -eq '0'){  
        $csv | Add-Member -MemberType NoteProperty -Name 'FirstName' -Value $User.FirstName -Force
        $csv | Add-Member -MemberType NoteProperty -Name 'LastName' -Value $User.LastName -Force
        $csv | Add-Member -MemberType NoteProperty -Name 'Tier' -Value '1' -Force
    }
}

在惨遭失败后,我向 StackOverflow 奇才寻求帮助。

我怎样才能实现这个目标?如何使用不同的层值复制第 0 层行,同时将所有其他数据保持不变到同一对象中?

最佳答案

这是一种方法,但请注意,此示例不会检查 Tier 1 是否有效。 Tier 0 的对象已存在对象。

$newCsv = Import-Csv ... | ForEach-Object {
    $_
    if ($_.Tier -eq 0) {
        $copy = $_.PSObject.Copy()
        $copy.Tier = 1
        $copy
    }
}

演示:

@'
FirstName|LastName|Tier
George|Smith|0
John|Fritz|1
Thomas|Adams|1
Manuel|Evans|0
'@ | ConvertFrom-Csv -Delimiter '|' | ForEach-Object {
    $_
    if ($_.Tier -eq 0) {
        $copy = $_.PSObject.Copy()
        $copy.Tier = 1
        $copy
    }
}

FirstName LastName Tier
--------- -------- ----
George    Smith    0
George    Smith    1
John      Fritz    1
Thomas    Adams    1
Manuel    Evans    0
Manuel    Evans    1

您的第一次尝试非常接近,问题是您正在添加一个哈希表 @{ ... }而不是自定义对象 [pscustomobject]@{ ... }$Csv ,那么它应该可以正常工作,但您也应该尽量避免 +=由于它效率低下,您可以这样做,最终与我上面的示例非常相似:

$csv = Import-Csv ...
$newCsv = foreach ($User in $csv) {
    $User
    if ($User.Tier -eq '0') {
        [pscustomobject]@{
            FirstName = $User.FirstName
            LastName  = $User.LastName
            Tier      = '1' 
        }
    }
}

如果您想添加 $Csv在不生成新数组的情况下,建议使用 List<T>及其 .Add方法。此方法还需要 for循环而不是 foreach否则,您会因在枚举时尝试改变集合而收到错误。

[System.Collections.Generic.List[object]] $csv = Import-Csv ...
for ($i = 0; $i -lt $csv.Count; $i++) {
    if ($csv[$i].Tier -eq '0') {
        $csv.Add([pscustomobject]@{
            FirstName = $User.FirstName
            LastName  = $User.LastName
            Tier      = '1' 
        })
    }
}

关于powershell - Import-CSV:将行(成员)添加到 foreach 循环中的结果对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76921424/

相关文章:

arrays - 用PowerShell上另一个数组中的元素替换数组中的元素

powershell - 在弹出窗口中读取主机的最简单方法?

powershell - 如何为每一行搜索导入的 CSV 单元格值

powershell - ExpandProperty - 管道中缺少的对象

powershell - 如何使用 PowerShell 在 cmd [提升] 中运行命令?

Powershell Rename-Item 一次性替换多个命名参数

powershell - 在 powershell 中读取具有可变列数的 CSV

Python CSV 导入在前 20 万行后花费太多时间

python - 每个 PowerShell 调用 Python 脚本并传递 PSObject 并返回解析的数据