如何在 foreach 循环中对导入的 csv 中的唯一值进行分组

How do you group unique values from imported csv in a foreach loop

我有一个包含以下内容的 txt 文件:

#test.txt

'ALDHT21;MIMO;1111;BOK;Tree'
'ALDHT21;MIMO;1211;BOK;Tree'
'PRGHT21;AIMO;1351;STE;Water'
'PRGHT21;AIMO;8888;FRA;Stone'
'ABCDT22;DIDO;8888;STE;Stone'
'PRA2HT21;ADDO;8888;STE;Stone'
';ADDO;1317;STE;Stone'

为了便于说明,我们给出上面的内容headers: ''Group;Code;ID;Signature;Type'

在 Powershell 的帮助下,我试图创建一个 foreach 循环,每个唯一的“签名”到 return 两个变量,这些变量具有来自“签名”所在行的唯一数据,然后混合在一起带有一些分隔符。

根据文件内容,预期结果如下:

第一个循环:

$Signature = "BOK" 

$Groups = "Tree:ALDHT21"

$Codes = "Tree:MIMO"

下一个循环:

$Signature = "FRA"

$Groups = "Stone:PRGHT21"

$Codes = "Stone:AIMO"

最后一个循环:

$Signature = "STE"

$Groups = "Stone:PRA2HT21,Stone:ABCDT22,Water:PRGHT21"

$Codes = "Stone:ADDO,Stone:DIDO,Water:AIMO"

注意最后一个循环应该跳过文件中的最后一个条目,因为它包含一个空组。

我的尝试并没有完全达到目标,我正在努力寻找一个好的方法来完成这个:

$file = "C:\temp\test.txt"
$uniqueSigs = (gc $file) -replace "'$|^'" | ConvertFrom-Csv -Delimiter ';' -Header Group,Code,ID,Signature,Type | group Signature
foreach ($sigs in $uniqueSigs) {
    $Groups = ""
    foreach ($Group in $sigs.Group) {
        $Groups += "$($Group.Type):$($Group.Group),"
    }
    $Groups = $Groups -replace ",$" 
    [PSCustomObject] @{
        Signatur = $sigs.Name
        Groups = $Groups
    }
    $Codes = ""
    foreach ($Group in $sigs.Group) {
        $Codes += "$($Group.Type):$($Group.Code),"
    }
    $Codes = $Codes -replace ",$" 
    [PSCustomObject] @{
        Signatur = $sigs.Name
        Codes = $Codes
    }
    $Signature = $sigs.Name
    If ($Group.Group){
    write-host "$Signature "-" $Groups "-" $Codes "
}
}

我的错误尝试结果:

BOK  - Tree:ALDHT21,Tree:ALDHT21 - Tree:MIMO,Tree:MIMO 
FRA  - Stone:PRGHT21 - Stone:AIMO

感谢任何帮助。 :)

您的变量命名有些混乱;以下简化的解决方案使用较少的变量,可能 产生所需的结果:

$file = "test.txt"
(Get-Content $file) -replace "'$|^'" | ConvertFrom-Csv -Delimiter ';' -Header Group,Code,ID,Signature,Type |
  Group-Object Signature |
    ForEach-Object {
      # Create and output an object with group information.
      # Skip empty .Group properties among the group's member objects.
      # Get the concatenation of all .Group and .Code column
      # values each, skipping empty groups and eliminating duplicates.
      $groups = (
        $_.Group.ForEach({ if ($_.Group) { "$($_.Type):$($_.Group)" } }) |
          Select-Object -Unique
      ) -join ","
      $codes = (
        $_.Group.ForEach({ "$($_.Type):$($_.Code)" }) |
          Select-Object -Unique
      ) -join ","
      # Create and output an object comprising the signature
      # and the concatenated groups and codes.
      [PSCustomObject] @{
          Signature = $_.Name
          Groups = $groups
          Codes = $codes
      }
      # Note: This is just *for-display* output.
      # Don't use Write-Host to output *data*.
      Write-Host ($_.Name, $groups, $codes -join ' - ')
    }

输出:

BOK - Tree:ALDHT21 - Tree:MIMO
FRA - Stone:PRGHT21 - Stone:AIMO
STE - Water:PRGHT21,Stone:ABCDT22,Stone:PRA2HT21 - Water:AIMO,Stone:DIDO,Stone:ADDO
Signature Groups                                     Codes
--------- ------                                     -----
BOK       Tree:ALDHT21                               Tree:MIMO
FRA       Stone:PRGHT21                              Stone:AIMO
STE       Water:PRGHT21,Stone:ABCDT22,Stone:PRA2HT21 Water:AIMO,Stone:DIDO,Stone:ADDO

请注意,用于显示 Write-Host 令人惊讶的是 先于 [pscustomobject] 实例的默认输出格式,这是由于异步行为.

中解释的隐式应用 Format-Table 格式