public/Get-Up.ps1
<#
.SYNOPSIS Gets the path of an ancestor directory, either by traversing upward by n levels or by finding the first ancestor matching a given search term. .PARAMETER n Number of levels above the starting location. (One by default.) .PARAMETER NamePart Directory name, partial directory name or path fragment for which to search. .PARAMETER From The directory from which to start. $PWD by default. .EXAMPLE # Get the parent of the current location C:\Windows\System32> Get-Up C:\Windows C:\Windows\System32> _ .EXAMPLE # Get the grandparent of the current location C:\Windows\System32\drivers\etc> Get-Up 2 C:\Windows\System32 C:\Windows\System32\drivers\etc> _ .EXAMPLE # Get the first ancestor containing the term 'win' C:\Windows\System32\drivers\etc> Get-Up win C:\Windows C:\Windows\System32\drivers\etc> _ .EXAMPLE # Get the root of each git repository below the current path C:\projects> ls .git -Force -Recurse -Depth 2 | gup C:\projects\cd-extras C:\projects\work\app ... C:\projects> _ .LINK Step-Up #> function Get-Up { [OutputType([String])] [CmdletBinding(DefaultParameterSetName = 'n')] param( [Parameter(ParameterSetName = 'n', Position = 0)] [byte] $n = 1, [Parameter(ParameterSetName = 'named', Position = 0, Mandatory)] [string] $NamePart, [Alias('FullName', 'Path')] [Parameter(ValueFromPipeline, ValueFromPipelineByPropertyName)] [string] $From = $PWD ) Process { $ancestors = @((Get-Ancestors -From $From).Path) if ($PSCmdlet.ParameterSetName -eq 'n') { if (!$n -or !$ancestors) { return $From } else { return $ancestors[$n - 1] } } if ($PSCmdlet.ParameterSetName -eq 'named') { if (($match = GetBestIndex $ancestors $NamePart) -ge 0) { $ancestors[$match] } else { Write-Error "Could not find '$NamePart' as an ancestor of '$From'." -ErrorAction Stop } } } } |