背景信息:
每个元素的IndicatorType为“' 10'或者' ND'
指标的值为“'!' ,'' (空字符串/ null),' o',' u'
问题:
我需要过滤每个"元素"中的数据。基于此伪代码规则的组,然后将结果导出到文件:
For Each" Element"分组如果指标='!'或者''对于BOTH IndicatorTypes(即' 10',' ND'),选择指示符类型= ND的组
ELSE如果指标='!'或者''对于IndicatorType = 10和指标=' o'或者' u' for IndicatorType = ND选择indicatorType = 10
我的源文件:
"Code","IndicatorType","Indicator","Element","Data"
"111","10","","S","0.039"
"111","10","!","Cr ","0.045"
"111","10","","Zn","0.011"
"111","10","!","P","0.013"
"111","10","","Ni ","56.480"
"111","10","!","Co ","1.081"
"111","10","!","Fe","45.655"
"111","10","!","Si","0.364"
"111","10","!","Mn","0.005"
"111","10","!","Al","0.007"
"111","10","!","Cu","0.014"
"111","10","!","Y","0.00"
"111","ND","","S","0.037"
"111","ND","","Cr ","0.039"
"111","ND","","Zn","0.010"
"111","ND","","P","0.013"
"111","ND","o","Ni ","37.107"
"111","ND","o","Co ","0.887"
"111","ND","o","Fe","37.430"
"111","ND","","Si","0.348"
"111","ND","","Mn","0.005"
"111","ND","","Al","0.008"
"111","ND","","Cu","0.013"
"111","ND","","Y","0.00"
按元素分组我的代码:
$myfile = Get-ChildItem -Path $myfileSource *.csv
$myfileData = Import-Csv $myfile.FullName | Group-Object Element |
Where-Object -FilterScript {($_.Group.IndicatorType -eq 'ND' -and
$_.Group.Indicator -eq '!' -or
$_.Group.Indicator -eq '') -or
($_.Group.IndicatorType -eq '10' -and
$_.Group.Indicator -eq 'o' -or
$_.Group.Indicator -eq 'u' -or
$_.Group.Indicator -eq '!' -or
$_.Group.Indicator -eq '')
}| Export-Csv -Path $myFile.FullName -Force -NoTypeInformation
PROBEM:
问题在于我的Where-Object,它返回所有值。
如何将伪代码规则应用于Where-Object以仅选择所需的组?
答案 0 :(得分:2)
$_.Group
将返回同一元素的两个对象,因此您的测试将使用-eq
右侧的值过滤列表(例如,组中两个对象的IndicatorType),并且条件很可能是真的。例如:
$_.Group.IndicatorType -eq 'ND'
#Translates to array of "IndicatorTypes in the group" -eq 'ND'
10,'ND' -eq 'ND'
#The line above filters the array on the left to show matching values, this returns
'ND'
#A value is always true, so this test will be
$true
您可以通过首先在要执行测试的组中查找对象来解决此问题。
此外,使用Group-Object Element | Where-Object …
意味着如果where子句为true,则将保留从Group-Object
返回的整个对象(包含Count,Name和elements-group)。您应该使用Foreach-Object
,因为您只想为每个已批准的元素组保留一个对象。尝试:
$myfile = Get-ChildItem -Path $myfileSource *.csv
$myfileData = Import-Csv $myfile.FullName |
#For Each "Element" Group
Group-Object Element | Foreach-Object {
$Ten = $_.Group | Where-Object { $_.IndicatorType -eq '10' }
$ND = $_.Group | Where-Object { $_.IndicatorType -eq 'ND' }
if(('!','' -contains $Ten.Indicator) -and ('!','' -contains $ND.Indicator)) {
#if Indicator='!' or '' for BOTH IndicatorTypes(ie '10','ND'), Select group where indicatorType=ND
$ND
} elseif (('!','' -contains $Ten.Indicator) -and ('o','u' -contains $ND.Indicator)) {
#ELSE if Indicator='!' or '' for IndicatorType = 10 and Indicator='o' or 'u' for IndicatorType=ND Select group where indicatorType=10
$Ten
}
} | Export-Csv -Path $myFile.FullName -Force -NoTypeInformation
答案 1 :(得分:0)
Group-Object
返回GroupInfo
个对象的集合,每个对象都包含组中元素的集合 - 基本上是列表列表。运行cmdlet会生成(基于示例输入)12个组的列表:
PS[1] (191) > $data = import-csv data2.txt | group-object element
PS[1] (192) > $data.Count
12
查看返回的第一项:
PS[1] > $data[0].Group.Count
2
您可以看到它包含两个看起来像这样的条目:
PS[1] (193) > $data[0].Group
Code : 111
IndicatorType : 10
Indicator :
Element : S
Data : 0.039
Code : 111
IndicatorType : ND
Indicator :
Element : S
Data : 0.037
这意味着您的选择条件必须应用于与该组关联的数据集合中的每个/所有条目,以决定是否要返回该组。在您的示例代码中,您似乎假设某个群体是平的而不是。但遗憾的是,我并不完全理解您要尝试的内容,因此我无法提供完整的答案。