想知道是否有人可以帮助我。问题是我正在尝试导入,分组,求和和导出CSV。问题是我的CSV的以下格式的列数未知。
GroupA,GroupB,GroupC,ValueA,ValueB,ValueC,ValueD ...
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
答案 0 :(得分:1)
导入此脚本后,将属性(列)分为组/值
它动态分组并仅对与数字无关的值字段求和
输入顺序由最终的选择对象维护
## Q:\Test\2019\01\17\SO_54237887.ps1
$csvImport = Import-Csv '.\input.csv'
$Cols = ($csvImport[0].psobject.Properties).Name
# get list of group columns by name and wildcard
$GroupCols = $Cols | Where-Object {$_ -like 'Group*'}
# a different approach would be to select a number of leading columns
# $GroupCols = $Cols[0..1]
$ValueCols = $Cols | Where-Object {$_ -notin $GroupCols}
$OutCols = ,'Groups' + $ValueCols
$csvGrouped = $csvImport | Group-Object $GroupCols | ForEach-Object{
$Props = @{Groups=$_.Name}
ForEach ($ValCol in $ValueCols){
$Props.Add($ValCol,($_.Group|Measure-Object $ValCol -Sum).Sum)
}
[PSCustomObject]$Props
}
$csvGrouped | Select-Object $OutCols
使用此示例输入文件
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
不对代码进行任何更改,它也处理来自Hassans答案的数据:
Groups ValueA ValueB ValueC
------ ------ ------ ------
Sam, Apple 30 4 20
Sam, Orange 50 4 5
Ian, Apple 15 3 3
答案 1 :(得分:1)
以下脚本应该起作用。请注意$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
,以及Group A,Group B,Group C,Value A,Value B
标头的更复杂数据。
编辑已根据beneficial LotPings' comment更新。
答案 2 :(得分:0)
script1.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