Powershell 在组内过滤-组对象
背景信息:Powershell 在组内过滤-组对象,powershell,Powershell,背景信息: 每个元素的指示符类型为“10”或“ND” 指示器的值为“!”、“”(空字符串/null)、'o'、'u' 问题: 我需要根据这个伪代码规则过滤每个“元素”组中的数据,然后将结果导出到文件: 对于每个“元素”组,如果指示器='!'或者对于两种指示符类型(即“10”、“ND”),选择其中指示符类型=ND的组 如果指示器='!'或“”表示IndicatorType=10,IndicatorType=ND表示Indicator='o'或'u'选择IndicatorType=10的组 我的源文
每个元素的指示符类型为“10”或“ND”
指示器的值为“!”、“”(空字符串/null)、'o'、'u'
问题:
我需要根据这个伪代码规则过滤每个“元素”组中的数据,然后将结果导出到文件:
对于每个“元素”组,如果指示器='!'或者对于两种指示符类型(即“10”、“ND”),选择其中指示符类型=ND的组
如果指示器='!'或“”表示IndicatorType=10,IndicatorType=ND表示Indicator='o'或'u'选择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
问题:问题在于我的Where对象,它返回所有的值
如何将伪代码规则应用于Where对象以仅选择所需的组?
$\uq>组将返回同一元素的两个对象,因此您的测试将使用-eq
右侧的值过滤列表(组中两个对象的指示符类型),条件很可能为真。例:
$_.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
,因为您只希望每个已批准的元素组保留一个对象。尝试:
$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
$\uq.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
,因为您只希望每个已批准的元素组保留一个对象。尝试:
$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
groupobject
返回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
这意味着您的选择标准必须应用于与组关联的数据集合中的每个/所有条目,以决定是否要返回该组。在您的示例代码中,您似乎假设一个组是平面的,而不是平面的。不幸的是,我不完全理解您试图做什么,因此我无法提供完整的答案。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
这意味着您的选择标准必须应用于与组关联的数据集合中的每个/所有条目,以决定是否要返回该组。在您的示例代码中,您似乎假设一个组是平面的,而不是平面的。不幸的是,我不完全理解您试图做什么,因此我无法提供完整的答案。我刚刚测试了,但仍然得到了每个组的两行(第10行)我的错误。忘记将组对象元素
之后的Where对象
更改为每个对象
。现在修复了我刚刚测试过,但仍然得到了每个组的两行(10/ND)我的坏。忘记将组对象元素
之后的Where对象
更改为每个对象
。现在修好了