Public/Find-MatchedPath.ps1
|
function Find-MatchedPath { <# .SYNOPSIS Search files and directories using path expressions that include embedded regular expressions. .DESCRIPTION Search files and directories using path expressions that include embedded regular expressions. .PARAMETER Expresion Path expression that includes regular expression. Regular expression must be surrounded them by << >>. .EXAMPLE PS> Find-MatchedPath -Expression C:\directory\to\seek\foler<<[ABC]>>\file<<06\d{2}>>.jpg .EXAMPLE PS> Find-MatchedPath -Expression file<<06\d{2}>>.jpg .EXAMPLE PS> Find-MatchedPath -Expression ..\..\foler<<[ABC]>>\file<<06\d{2}>>.jpg .EXAMPLE PS> Find-MatchedPath -Expression \\host\shared\directory\foler<<[ABC]>>\file<<06\d{2}>>.jpg .OUTPUTS System.Array of PSCustomObject. Each object contains the following properties: - Path : FullName of file or directory matched with Expression - <capture goups> : String captured by regular expression (1, 2, 3,..) .LINK https://github.com/hiroaki415/Find-MatchedPath/tree/main .NOTES Author: hiroaki415 #> [CmdletBinding()] Param( [Parameter(Mandatory)] [string]$Expression ) $repath = Resolve-Expression -Expression $Expression $tokens = Split-RegexPath -RegexPath $repath $currentItems = @(Get-ChildItem -LiteralPath ([Regex]::Unescape($tokens[0]) + "\") -ErrorAction SilentlyContinue) $i = 1 for (; $i -lt ($tokens.Count - 1); $i++) { $pattern = "^$($tokens[$i])$" $nextItems = @() foreach ($item in $currentItems) { if ($tokens[$i] -eq "\.") { $nextItems += $item } elseif ($tokens[$i] -eq "\.\.") { $parentPath = Split-Path -Path $item.PSParentPath -Parent $children = @(Get-ChildItem -LiteralPath $parentPath -ErrorAction SilentlyContinue) # $nextItems = @(($nextItems + $children) | Select-Object -Unique) $nextItems = @(($nextItems + $children) | Group-Object FullName | ForEach-Object { $_.Group[0] }) } elseif ($item.PSIsContainer -and $item.Name -match $pattern) { $children = @(Get-ChildItem -LiteralPath $item.FullName -ErrorAction SilentlyContinue) # $nextItems = @(($nextItems + $children) | Select-Object -Unique) $nextItems = @(($nextItems + $children) | Group-Object FullName | ForEach-Object { $_.Group[0] }) } } if ($nextItems.Count -le 0) { return , @() } $currentItems = $nextItems } $matchedPaths = @() foreach ($item in $currentItems) { $fullPattern = ConvertTo-FullRegexPath -Tokens $tokens -ItemPath $item.FullName if ($item.FullName -match "^$fullPattern$") { $obj = [PSCustomObject]@{ Path = $item.FullName } for ($j = 1; $Matches.ContainsKey($j); $j++) { $obj | Add-Member -MemberType NoteProperty -Name $j -Value $Matches[$j] } $matchedPaths += $obj } } return , $matchedPaths } |