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对象
更改为
每个对象
。现在修好了