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