【发布时间】:2010-11-26 09:14:18
【问题描述】:
如何从 PowerShell 数组中删除重复项?
$a = @(1,2,3,4,5,5,6,7,8,9,0,0)
【问题讨论】:
标签: arrays powershell
如何从 PowerShell 数组中删除重复项?
$a = @(1,2,3,4,5,5,6,7,8,9,0,0)
【问题讨论】:
标签: arrays powershell
将Select-Object(别名为select)与-Unique 开关一起使用;例如:
$a = @(1,2,3,4,5,5,6,7,8,9,0,0)
$a = $a | select -Unique
【讨论】:
Get-Unique(或 gu)。
-u。 select -u 我会在命令行上使用它,但是写在代码中,建议使用完整的 PS 措辞:Select-Object -Unique
另一种选择是将Sort-Object(别名为sort,但仅在Windows 上)与-Unique 开关结合使用,该开关结合了排序和删除重复项:
$a | sort -unique
【讨论】:
@("B", "a", "A") | sort -unique 产生 A B。
如果您想完全防弹,我的建议是:
@('Apples', 'Apples ', 'APPLES', 'Banana') |
Sort-Object -Property @{Expression={$_.Trim()}} -Unique
输出:
Apples
Banana
这使用Property 参数来首先Trim() 字符串,因此多余的空格被删除,然后只选择-Unique 值。
更多信息Sort-Object:
Get-Help Sort-Object -ShowWindow
【讨论】:
Get-Unique 没有工作,因为空格
$a | sort -unique
这适用于不区分大小写的情况,因此可以删除具有不同大小写的重复字符串。解决了我的问题。
$ServerList = @(
"FS3",
"HQ2",
"hq2"
) | sort -Unique
$ServerList
以上输出:
FS3
HQ2
【讨论】:
这就是您如何从具有两个或多个属性的数组中获得唯一性。排序至关重要,也是使其正常工作的关键。否则,您只会退回一件商品。
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/
【讨论】:
如果列表已排序,您可以使用Get-Unique cmdlet:
$a | Get-Unique
【讨论】:
使用我的方法,您可以完全删除重复值,只留下计数为 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
无论您使用的是从 Powershell 2.0 到 5.1 的 SORT -UNIQUE、SELECT -UNIQUE 还是 GET-UNIQUE,给出的所有示例都在单列数组上。我还没有让它跨具有多个列的数组起作用,以 REMOVE 重复行以在所述列中留下单个出现的行,或开发替代脚本解决方案。取而代之的是,这些 cmdlet 只返回了一个数组中的行,这些行在单次出现的情况下出现了一次,并转储了所有重复的内容。通常我必须从 Excel 中的最终 CSV 输出中手动删除重复项才能完成报告,但有时我想在删除重复项后继续在 Powershell 中处理所述数据。
【讨论】:
要从数组中获取唯一项并保留它们的顺序,您可以使用 .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)
【讨论】:
许多提供的答案给出了错误的结果。
select -Unqiue 不区分大小写。
sort -Unique 为您提供排序结果,您可能希望按照原始顺序。
Will 给出了一个很好的答案,但它有缺陷,因为它会丢弃所有重复的结果,但忘记保留其中一个。
这是我创建的一个似乎可以完美运行的版本。它会返回独特的结果并保留原始排序顺序。
($properties | Group-Object -NoElement).Name | Get-Unique
【讨论】: