Как удалить дубликаты файлов из массива - PullRequest
1 голос
/ 31 января 2020

Немного отличается от других. Я получаю массив файлов для обработки (в основном это обработка регистрации 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

Ответы [ 2 ]

2 голосов
/ 31 января 2020

Используйте хеш-таблицу для отслеживания последнего файла, который просматривали для указанного c имени файла:

$files = @{}

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

$uniqueFiles = $files.Values
0 голосов
/ 31 января 2020

Полезный ответ Матиаса Р. Йессена , вероятно, является лучшим (самым быстрым) решением в этом случае, но вот альтернатива, основанная на командлете Group-Object:

Get-ChildItem -LiteralPath $PSScriptRoot -Recurse -Filter *.dll |
  Where-Object FullName -notmatch dll_Old |
    Group-Object Name |
      ForEach-Object { $_.Group[-1] }
  • Group-Object Name группирует все соответствующие файлы по свойству .Name.

  • ForEach-Object { $_.Group[-1] }, затем извлекает последний ( -1) член каждой результирующей группы.

Обратите внимание, что Group-Object будет неявно сортировать группы по свойству группировки, поэтому результирующий список объектов информации о файле () System.IO.FileInfo, как вывод Get-ChildItem) будет отсортировано по имени файла.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...