Powershell 对列数未知的CSV进行分组和求和

Powershell 对列数未知的CSV进行分组和求和,powershell,Powershell,想知道是否有人能帮助我。问题是我正在尝试导入、分组、求和并导出CSV。问题是我的CSV有以下格式的未知列数 组A,组B,组C,值A,值B,值C,值 GroupA、B和C是常量,我想要分组的字段-我预先知道这些字段的名称。问题是有未知数量的值列-我想对所有这些列求和(并且事先不知道这些列的名称) 如果我知道值字段的名称,并且有固定数量的值字段,那么我就可以轻松地使用这段代码。但我正在努力获取未知名称和列数的代码 $csvImport = import-csv 'C:\input.csv' $cs

想知道是否有人能帮助我。问题是我正在尝试导入、分组、求和并导出CSV。问题是我的CSV有以下格式的未知列数

组A,组B,组C,值A,值B,值C,值

GroupA、B和C是常量,我想要分组的字段-我预先知道这些字段的名称。问题是有未知数量的值列-我想对所有这些列求和(并且事先不知道这些列的名称)

如果我知道值字段的名称,并且有固定数量的值字段,那么我就可以轻松地使用这段代码。但我正在努力获取未知名称和列数的代码

$csvImport = import-csv 'C:\input.csv'

$csvGrouped = $csvImport | Group-Object -property GroupA,GroupB,GroupC

$csvGroupedFinal = $csvGrouped | Select-Object @{Name = 'GroupA';Expression={$_.Values[0]}},
        @{Name = 'GroupB';Expression={$_.Values[1]}},
        @{Name = 'GroupC';Expression={$_.Values[2]}},                      
        @{Name = 'ValueA' ;Expression={
                ($_.Group|Measure-Object 'ValueA' -Sum).Sum
        }}

$csvGroupedFinal | Export-Csv 'C:\output.csv' -NoTypeInformation
示例输入数据-

GroupA, GroupB, Value A  
Sam, Apple, 10  
Sam, Apple, 20  
Sam, Orange, 50  
Ian, Apple, 15  
GroupA, GroupB, Value A  
Sam, Apple, 30  
Sam, Orange, 50  
Ian, Apple, 15
输出数据-

GroupA, GroupB, Value A  
Sam, Apple, 10  
Sam, Apple, 20  
Sam, Orange, 50  
Ian, Apple, 15  
GroupA, GroupB, Value A  
Sam, Apple, 30  
Sam, Orange, 50  
Ian, Apple, 15

导入后,此脚本将属性(列)拆分为组/值

  • 它动态分组,只在值字段上求和,与数字无关

  • 输入顺序由最终选择对象维护


使用此示例输入文件

GroupA GroupB ValueA ValueB
------ ------ ------ ------
Sam    Apple  10     15
Sam    Apple  20     25
Sam    Orange 50     75
Ian    Apple  15     20
任意数量的组和值的样本输出

Groups      ValueA ValueB
------      ------ ------
Sam, Apple      30     40
Sam, Orange     50     75
Ian, Apple      15     20
在不改变任何代码的情况下,它也会处理来自Hassan answer的数据:

Groups      ValueA ValueB ValueC
------      ------ ------ ------
Sam, Apple      30      4     20
Sam, Orange     50      4      5
Ian, Apple      15      3      3
脚本1.ps1

Import-Csv 'input.csv' | `
Group-Object -Property GroupA,GroupB | `
% {$b=$_.name -split ', ';$c=($_.group | `
Measure-Object -Property Value* -Sum).Sum;
[PScustomobject]@{GroupA=$b[0];
GroupB=$b[1];
Sum=($c | Measure-Object -Sum).Sum }}
input.csv

GroupA, GroupB, ValueA, ValueB, ValueC
Sam, Apple, 10, 1, 10
Sam, Apple, 20, 3, 10
Sam, Orange, 50, 4, 5
Ian, Apple, 15, 3, 3
输出

PS D:\coding> .\script1.ps1

GroupA GroupB Sum
------ ------ ---
Sam    Apple   54
Sam    Orange  59
Ian    Apple   21

下面的脚本应该可以工作。请注意
$FixedNames
变量:

$csvImport = @"
Group A,Group B,Value A
sam,apple,10
sam,apple,20
sam,orange,50
ian,apple,15
"@ | ConvertFrom-Csv

$FixedNames  = @('Group A', 'Group B', 'Group C')
# $aux         = ($csvImport|Get-Member -MemberType NoteProperty).Name  ### sorted (wrong)
$aux         = ($csvImport[0].psobject.Properties).Name                 ### not sorted
$auxGrpNames = @( $aux     | Where-Object {$_    -in $FixedNames})
$auxValNames = @( $aux     | Where-Object {$_ -notin $FixedNames})
$csvGrouped  = $csvImport  | Group-Object -property $auxGrpNames
$csvGroupedFinal = $csvGrouped | 
    ForEach-Object {
        ($_.Name.Replace(', ',','), (($_.Group |
            Measure-Object -Property $auxValNames -Sum
                ).Sum -join ',')) -join ','
    } | ConvertFrom-Csv -Header $aux
$csvGroupedFinal
同样测试

$csvImport = @"
Group A,Group B,Value A,Value B
sam,apple,10,1
sam,apple,20,
sam,orange,50,5
ian,apple,15,51
"@ | ConvertFrom-Csv
以及
组A、组B、组C、值A、值B的更复杂数据
标题


编辑根据更新。

您应该提供输入和预期输出的样本数据。我不清楚您是要对每行的列进行求和,还是要对每列的所有行进行合计。每列的所有行的合计给出了一些示例数据。谢谢你!您必须使用powershell吗?这可以用python轻松完成。不幸的是,我不能使用python,我在一个受限的工作环境中。谢谢你的回复。如果您不介意演示的话,我正在努力解决的是循环多个值(未知数)。对不起。我编辑了你的答案而不是我自己的答案。希望同行评议会发现这个错误并取消编辑。您也可以添加回您的答案。@SamDolbear现在为[PSCustomObject]动态创建属性,谢谢您的编辑,看起来和我需要的一模一样!那么,对上述问题的答案是向上投票还是拆分?还是更改答案?嗨,谢谢你的回答。不幸的是,这与我问题中的代码相同,但如果我想将其扩展为未知数量的“值”(值A、值B、值C…)——这需要动态确定,则它将不起作用。@SamDolbear请参见上面编辑的答案。与公认的答案不同,但可能对现在或其他时间有用,也可能对其他人有用。非常感谢!看来是我需要的!再次感谢!返回工作时将进行测试。@SamDolbear不幸的是,解决方案取决于原始CSV中的列名:
Get Member-MemberType NoteProperty
数组似乎按
Name
属性排序。因此,最好以另一种方式(例如,通过解析标题行)获取变量
$aux
$auxGrpNames
$auxValNames
!提示:使用
Get Content
读取变量的标题,将其拆分为
$aux
变量。可以使用未排序方式
$aux=($csvImport[0].psobject.Properties).Name
获取标题。前三个用于排序
$auxGrpNames=$aux[0..2]