【问题标题】:Removing duplicate values from a PowerShell array从 PowerShell 数组中删除重复值
【发布时间】:2010-11-26 09:14:18
【问题描述】:

如何从 PowerShell 数组中删除重复项?

$a = @(1,2,3,4,5,5,6,7,8,9,0,0)

【问题讨论】:

    标签: arrays powershell


    【解决方案1】:

    Select-Object(别名为select)与-Unique 开关一起使用;例如:

    $a = @(1,2,3,4,5,5,6,7,8,9,0,0)
    $a = $a | select -Unique
    

    【讨论】:

    • 这太简单了 :-(。在 PowerShell 2 中,如果您的数组已经排序,您也可以使用 Get-Unique(或 gu)。
    • Johannes,Get-Unique 在 v1 中可用 :)
    • 酷,这很好用,只是一个注释,如果你想简洁,它甚至可以缩短为-uselect -u 我会在命令行上使用它,但是写在代码中,建议使用完整的 PS 措辞:Select-Object -Unique
    • 这仅适用于单个数字?对于大量的数组列表,它似乎不起作用。
    • 这对我来说不能正常工作,它只保留一个重复的值,几乎就像它在创建重复列表一样。
    【解决方案2】:

    另一种选择是将Sort-Object(别名为sort,但仅在Windows 上)与
    -Unique 开关结合使用,该开关结合了排序和删除重复项:

    $a | sort -unique
    

    【讨论】:

    • 这也解决了我的下一个问题,即如何对其进行排序。谢谢!
    • 这个看起来也快了一点。
    • 请注意,这不会保留元素的顺序,例如@("B", "a", "A") | sort -unique 产生 A B
    • 这是更好的答案。 select -unique 不区分大小写
    【解决方案3】:

    如果您想完全防弹,我的建议是:

    @('Apples', 'Apples ', 'APPLES', 'Banana') | 
        Sort-Object -Property @{Expression={$_.Trim()}} -Unique
    

    输出:

    Apples
    Banana
    

    这使用Property 参数来首先Trim() 字符串,因此多余的空格被删除,然后只选择-Unique 值。

    更多信息Sort-Object:

    Get-Help Sort-Object -ShowWindow
    

    【讨论】:

    • 很棒的答案。解决了我的问题,Get-Unique 没有工作,因为空格
    【解决方案4】:
    $a | sort -unique
    

    这适用于不区分大小写的情况,因此可以删除具有不同大小写的重复字符串。解决了我的问题。

    $ServerList = @(
        "FS3",
        "HQ2",
        "hq2"
    ) | sort -Unique
    
    $ServerList
    

    以上输出:

    FS3
    HQ2
    

    【讨论】:

    • 这也适用于具有多个成员的数组
    【解决方案5】:

    这就是您如何从具有两个或多个属性的数组中获得唯一性。排序至关重要,也是使其正常工作的关键。否则,您只会退回一件商品。

    PowerShell 脚本:

    $objects = @(
        [PSCustomObject] @{ Message = "1"; MachineName = "1" }
        [PSCustomObject] @{ Message = "2"; MachineName = "1" }
        [PSCustomObject] @{ Message = "3"; MachineName = "1" }
        [PSCustomObject] @{ Message = "4"; MachineName = "1" }
        [PSCustomObject] @{ Message = "5"; MachineName = "1" }
        [PSCustomObject] @{ Message = "1"; MachineName = "2" }
        [PSCustomObject] @{ Message = "2"; MachineName = "2" }
        [PSCustomObject] @{ Message = "3"; MachineName = "2" }
        [PSCustomObject] @{ Message = "4"; MachineName = "2" }
        [PSCustomObject] @{ Message = "5"; MachineName = "2" }
        [PSCustomObject] @{ Message = "1"; MachineName = "1" }
        [PSCustomObject] @{ Message = "2"; MachineName = "1" }
        [PSCustomObject] @{ Message = "3"; MachineName = "1" }
        [PSCustomObject] @{ Message = "4"; MachineName = "1" }
        [PSCustomObject] @{ Message = "5"; MachineName = "1" }
        [PSCustomObject] @{ Message = "1"; MachineName = "2" }
        [PSCustomObject] @{ Message = "2"; MachineName = "2" }
        [PSCustomObject] @{ Message = "3"; MachineName = "2" }
        [PSCustomObject] @{ Message = "4"; MachineName = "2" }
        [PSCustomObject] @{ Message = "5"; MachineName = "2" }
    )
    
    Write-Host "Sorted on both properties with -Unique" -ForegroundColor Yellow
    $objects | Sort-Object -Property Message,MachineName -Unique | Out-Host
    
    Write-Host "Sorted on just Message with -Unique" -ForegroundColor Yellow
    $objects | Sort-Object -Property Message -Unique | Out-Host
    
    Write-Host "Sorted on just MachineName with -Unique" -ForegroundColor Yellow
    $objects | Sort-Object -Property MachineName -Unique | Out-Host
    

    输出:

    Sorted on both properties with -Unique
    
    Message MachineName
    ------- -----------
    1       1          
    1       2          
    2       1          
    2       2          
    3       1          
    3       2          
    4       1          
    4       2          
    5       1          
    5       2          
    
    
    Sorted on just Message with -Unique
    
    Message MachineName
    ------- -----------
    1       1          
    2       1          
    3       1          
    4       1          
    5       2          
    
    
    Sorted on just MachineName with -Unique
    
    Message MachineName
    ------- -----------
    1       1          
    3       2  
    

    来源: https://powershell.org/forums/topic/need-to-unique-based-on-multiple-properties/

    【讨论】:

    • 对于你可能不知道标题的循环(即自动解析一些 csv 数据) - 使用 Sort-Object * -unique
    【解决方案6】:

    如果列表已排序,您可以使用Get-Unique cmdlet:

     $a | Get-Unique
    

    【讨论】:

    • 需要事先对列表进行排序
    【解决方案7】:

    使用我的方法,您可以完全删除重复值,只留下计数为 1 的数组中的值。目前尚不清楚这是否是 OP 真正想要的,但是我无法找到这样的示例在线解决方案,就在这里。

    $array=@'
    Bananna
    Apple
    Carrot
    Pear
    Apricot
    Pear
    Bananna
    '@ -split '\r\n'
    
    ($array | Group-Object -NoElement | ?{$_.count -eq 1}).Name
    

    【讨论】:

    • 我真的很喜欢这个答案,但它有一个很大的缺陷。如果有多个具有相同名称的元素,则所有这些元素都会丢失,它应该保留其中一个。这修复了它:($properties | Group-Object -NoElement).Name | Get-Unique
    【解决方案8】:

    无论您使用的是从 Powershell 2.0 到 5.1 的 SORT -UNIQUESELECT -UNIQUE 还是 GET-UNIQUE,给出的所有示例都在单列数组上。我还没有让它跨具有多个列的数组起作用,以 REMOVE 重复行以在所述列中留下单个出现的行,或开发替代脚本解决方案。取而代之的是,这些 cmdlet 只返回了一个数组中的行,这些行在单次出现的情况下出现了一次,并转储了所有重复的内容。通常我必须从 Excel 中的最终 CSV 输出中手动删除重复项才能完成报告,但有时我想在删除重复项后继续在 Powershell 中处理所述数据。

    【讨论】:

    • 这是 Where-Object 派上用场的地方。您首先使用正确的 where 子句缩小列表范围,然后将其通过管道传递给排序对象,选择一个或多个列进行排序,并为排序对象赋予 -unique。
    • @Christopher,请参阅我的帖子来解决您的问题。考虑删除此答案以清理解决方案。
    【解决方案9】:

    要从数组中获取唯一项并保留它们的顺序,您可以使用 .NET HashSet:

    $Array = @(1, 3, 1, 2)
    $Set = New-Object -TypeName 'System.Collections.Generic.HashSet[int]' -ArgumentList (,[int[]]$Array)
    
    # PS>$Set
    # 1
    # 3
    # 2
    

    最适合同时包含大写和小写项目的字符串数组,您需要以不区分大小写的方式保留每个项目的第一次出现:

    $Array = @("B", "b", "a", "A")
    $Set = New-Object -TypeName 'System.Collections.Generic.HashSet[string]' -ArgumentList ([string[]]$Array, [StringComparer]::OrdinalIgnoreCase)
    
    # PS>$Set
    # B
    # a
    

    与其他类型按预期工作。

    缩短语法,兼容 PowerShell 5.1 及更高版本:

    $Array = @("B", "b", "a", "A")
    $Set = [Collections.Generic.HashSet[string]]::new([string[]]$Array, [StringComparer]::OrdinalIgnoreCase)
    
    $Array = @(1, 3, 1, 2)
    $Set = [Collections.Generic.HashSet[int]]::new([int[]]$Array)
    

    【讨论】:

      【解决方案10】:

      许多提供的答案给出了错误的结果。 select -Unqiue 不区分大小写。 sort -Unique 为您提供排序结果,您可能希望按照原始顺序。

      Will 给出了一个很好的答案,但它有缺陷,因为它会丢弃所有重复的结果,但忘记保留其中一个。

      这是我创建的一个似乎可以完美运行的版本。它会返回独特的结果并保留原始排序顺序。

      ($properties | Group-Object -NoElement).Name | Get-Unique

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-10-10
        • 2019-10-19
        • 2021-07-29
        • 2021-04-02
        相关资源
        最近更新 更多