Powershell CSV 导入。如果用户名匹配,则将值加在一起

Powershell CSV Import. Adding values together if username match

我将以下 CSV 文件导入到 Powershell 数组中

  User     Today  MTD
  ----     -----  ---
  User1    5      15
  User1    3      32
  User2    2      5
  User1    1      23
  User2    3      34
  User3    3      34

如果用户匹配,我想将 Today 和 MTD 数字添加到一行

示例:用户 1 将是“今天”5+3+1=9“MTD”15+32+23=70

所需输出:

  User     Today  MTD
  ----     -----  ---
  User1    9      70
  User2    5      39
  User3    3      34

我可以使用

列出一个用户名的数据

$arr.Where({$_.User -eq "user1"})

但不知道如何将今天和 MTD 加在一起[=13​​=]

好了,我回答了一个非常相似的问题

代码:

$csv = @'
User,Today,MTD
User1,5,15
User1,3,32
User2,2,5
User1,1,23
User2,3,34
User3,3,34
'@ | ConvertFrom-Csv

$csv | Group-Object User | ForEach-Object {
    $_.Group[0].Today = ($_.Group.Today | Measure-Object -Sum).Sum
    $_.Group[0].MTD = ($_.Group.MTD | Measure-Object -Sum).Sum
    $_.Group[0]
}

输出:

User  Today MTD
----  ----- ---
User1     9  70
User2     5  39
User3     3  34

编辑

要导出结果,您可以这样做:

$csv | Group-Object User | ForEach-Object {
    # Original code here...
} | Export-Csv newCsv.csv -NoTypeInformation

或者,如果你想在内存中保存新对象:

$newCsv = $csv | Group-Object User | ForEach-Object {
    # Original code here...
}

$newCsv | Export-Csv newCsv.csv -NoTypeInformation

添加到,类似的解决方案,但既然已经写好了,我不妨分享一下...

我使用自定义对象设置测试数据,为简洁起见,我将其省略。

Import-Csv 'c:\temp\TestCsvData.csv' | 
Group-Object -Property User |
ForEach-Object{
    $SumToday = ($_.Group | Measure-Object -Property Today -Sum).Sum
    $SumMTD   = ($_.Group | Measure-Object -Property MTD -Sum).Sum
    
    [PSCustomObject]@{
            User  = $_.Name
            Today = $SumToday
            MTD   = $SumMTD
        }
    } |
Export-Csv -Path 'c:\temp\NewCsvFile.csv' -NoTypeInformation

这会输出新对象,而不是选择和操作组中的第一个对象。如果需要,您可以在此之后添加新的 Export-Csv 命令以获取新的 CSV 文件。

替代方法,仅供娱乐:

$Hash = [Ordered]@{}

Import-Csv 'c:\temp\TestCsvData.csv' |
ForEach-Object{
    If( $Hash.Contains( $_.User ) ) {    
        [Int]$Hash[$_.User].Today += $_.Today
        [Int]$Hash[$_.User].MTD   += $_.MTD
    }
    Else {
        $Hash[$_.User] = $_
    }
}

$Hash.Values | Export-Csv -Path 'c:\temp\NewCsvFile.csv' -NoTypeInformation

这不使用 Group-Object。它肯定更难阅读,但主要是因为需要进行类型转换以确保您添加的是数字而不是字符串。但是,我试图通过将转换一直向左移动而不是转换右操作数来最小化它,PowerShell 的类型转换引擎将为我们处理这个问题。

这与 Santiago 的示例有点相似,因为它采用为给定用户找到的第一个对象,并在遇到具有相同用户名的其他对象时简单地更新其属性。然而,与其他示例不同的是,这并不是纯粹地顺着管道流下来。因此,它可能会使用更多内存,这只是在极端情况下才会出现的问题。