functions/private/Filter-KlippyItemByWildcard.ps1
|
function Filter-KlippyItemByWildcard { <# .SYNOPSIS Filters file/folder items by wildcard pattern. .DESCRIPTION Performs case-insensitive wildcard matching on file/folder names. Matches against leaf name only (not full path). .PARAMETER Items Collection of items to filter. .PARAMETER Pattern Wildcard pattern to match. .PARAMETER PathProperty The property name containing the path. Default is 'Path'. .PARAMETER RequireSingle If true, throws an error if multiple items match. .OUTPUTS Filtered collection of items. #> [CmdletBinding()] param( [Parameter(Mandatory = $true, ValueFromPipeline = $true)] [AllowEmptyCollection()] $Items, [Parameter(Mandatory = $true)] [string]$Pattern, [Parameter()] [string]$PathProperty = 'Path', [Parameter()] [switch]$RequireSingle ) begin { $allItems = [System.Collections.Generic.List[object]]::new() } process { foreach ($item in $Items) { $allItems.Add($item) } } end { # If pattern has no wildcards, match exactly $hasWildcard = $Pattern -match '[\*\?\[\]]' $matches = foreach ($item in $allItems) { $path = $item.$PathProperty if (-not $path) { continue } $leafName = Split-Path $path -Leaf if ($hasWildcard) { # Wildcard matching (case-insensitive) if ($leafName -like $Pattern -or $path -like $Pattern) { $item } } else { # Exact matching (case-insensitive) if ($leafName -ieq $Pattern -or $path -ieq $Pattern) { $item } } } # Convert to array $matchArray = @($matches) if ($RequireSingle) { if ($matchArray.Count -eq 0) { throw "No items matching '$Pattern' found." } if ($matchArray.Count -gt 1) { $names = ($matchArray | Select-Object -First 5 | ForEach-Object { $_.$PathProperty }) -join ', ' throw "Multiple items match '$Pattern': $names. Please be more specific." } return $matchArray[0] } return $matchArray } } |