Arrays 如何从arraylist中删除重复文件

Arrays 如何从arraylist中删除重复文件,arrays,powershell,sorting,Arrays,Powershell,Sorting,和其他的有点不同。我正在检索要处理的文件的arraylist(基本上是在本地计算机上处理DLL注册),我需要我的脚本来正确处理具有相同名称的多个DLL。select-Unique不起作用,因为从技术上讲,文件不是重复的,每个文件都有自己唯一的完整路径 我需要这个脚本来检索文件夹(以及子文件夹)中的所有DLL,但只返回每个命名文件的最后一个实例。例如,如果我有文件: C:\Path\Update1\GRM.DLL C:\Path\Update1\HTCP.DLL C:\Path\Update2\

和其他的有点不同。我正在检索要处理的文件的arraylist(基本上是在本地计算机上处理DLL注册),我需要我的脚本来正确处理具有相同名称的多个DLL。
select-Unique
不起作用,因为从技术上讲,文件不是重复的,每个文件都有自己唯一的完整路径

我需要这个脚本来检索文件夹(以及子文件夹)中的所有DLL,但只返回每个命名文件的最后一个实例。例如,如果我有文件:

  • C:\Path\Update1\GRM.DLL
  • C:\Path\Update1\HTCP.DLL
  • C:\Path\Update2\GRM.DLL
  • C:\Path\Update3\GRM.DLL
脚本应返回Update3\GRM.DLL和Update1\HTCP.DLL的对象

[System.Collections.ArrayList]$dlls = @(Get-ChildItem -Path $PSScriptRoot -Recurse | Where-Object 
{$_.Extension -eq ".dll" -and $_.FullName -notmatch 'dll_Old'})
编辑:我已经准备好了,但是它选择了第一个出现的实例,我需要最后一个。在本例中,这意味着它正在拦截Update1/GRM.DLL,而不是Update3/GRM.DLL

$dlls = @(Get-ChildItem -Path $PSScriptRoot -Recurse | Where-Object {$_.Extension -eq ".dll" -and $_.FullName -notmatch 'dll_Old'}) | Select-Object -Unique

使用哈希表跟踪特定文件名的最后一个文件:

$files = @{}

Get-ChildItem -Path $PSScriptRoot -File -Recurse -Filter *.dll |Where-Object FullName -notmatch 'dll_Old' |ForEach-Object {
    $files[$_.Name] = $_
}

$uniqueFiles = $files.Values
可能是这种情况下最好(最快)的解决方案,但这里有一个基于cmdlet的替代方案:

  • Group Object Name
    根据其
    .Name
    属性对所有匹配文件进行分组

  • ForEach对象{$\.Group[-1]}
    然后从每个结果组中提取最后一个(
    -1
    )成员


请注意,
Group Object
将根据grouping属性对组进行隐式排序,因此生成的文件信息对象列表(,作为
Get ChildItem
的输出)将按照文件名进行排序。

在叶上使用Select Unique(拆分路径-叶)或者查看Group Object cmdlet-具体取决于您希望如何使用输出。@谢谢!实际上,它与更新的代码一起运行,但它选择了错误的唯一值。
Get-ChildItem -LiteralPath $PSScriptRoot -Recurse -Filter *.dll |
  Where-Object FullName -notmatch dll_Old |
    Group-Object Name |
      ForEach-Object { $_.Group[-1] }