PowerShell返回路径中最后一个现有文件夹

1rhkuytd  于 2023-06-23  发布在  Shell
关注(0)|答案(3)|浏览(142)

我需要一些帮助,因为test-path只返回$true$false
我需要从$path返回最后一个存在的文件夹。

$path = \\test.pl\power\shell\test\company

但最后一个存在的是\shell文件夹。
那么如何得到一个像这样的返回值:

$existingpath = \\test.pl\power\shell
$notexisting = \test\company
pes8fvy9

pes8fvy91#

尝试使用管道解决此问题:

$path = '\\test.pl\power\shell\test\company'

# Create an array that consists of the full path and all parents
$pathAndParents = for( $p = $path; $p; $p = Split-Path $p ) { $p }

# Find the first existing path
$existingPath = $pathAndParents | Where-Object { Test-Path $_ } | Select-Object -First 1

# Extract the non-existing part of the path
$nonExistingPath = $path.SubString( $existingPath.Length + 1 )

for循环创建了一个临时变量$p,这样原始路径就不会被破坏。在每次迭代时,它输出变量$p,由于PowerShell的隐式输出行为,该变量会自动添加到数组中。然后将$p设置为$p的父路径(带有单个未命名参数的Split-Path返回父路径)。当不再有父级时,循环退出。
Where-Object | Select-Object行看起来效率不高,但由于Select-Object参数-First 1,它实际上只测试了必要数量的路径。当找到第一个现有路径时,将退出管道(类似于循环中的break语句)。
以上是公认的答案。随后添加了以下解决方案。它的效率更高,因为它只根据需要调用Split-Path,而不需要Where-ObjectSelect-Object

$path = '\\test.pl\power\shell\test\company'

# Find the first existing path
for( $existingPath = $path; 
     $existingPath -and -not (Test-Path $existingPath);
     $existingPath = Split-Path $existingPath ) {}

# Extract the non-existing part of the path
$nonExistingPath = $path.SubString( $existingPath.Length + 1 )
r3i60tvu

r3i60tvu2#

您可以使用Split-PathTest-Pathwhile循环逐个检查每个文件夹路径:

$path = '.\test.pl\power\shell\test\company'

# Check folder at current path
while(-not(Test-Path $path)){
  # Move on to the parent folder
  $path = $path |Split-Path
}

# $path will now be `'.\test.pl\power\shell'`
$path
rjee0c15

rjee0c153#

除了第一个答案之外,优选的是在处理之前解析和测试所传递路径的根:

$path = '\\test.pl\power\shell\test\company'
$resolvedPath = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($path)

$root = Split-Path $resolvedPath -Qualifier
if (Test-Path $root -PathType Container) {
    while (-not (Test-Path $resolvedPath -PathType Container)) {
        $resolvedPath = Split-Path $resolvedPath
    }
} else {
    $resolvedPath = ''
}
$resolvedPath

或者使用.NET方法:

$root = [System.IO.Path]::GetPathRoot($resolvedPath)
if ([System.IO.Directory]::Exists($root)) {
    while (-not [System.IO.Directory]::Exists($resolvedPath)) {
        $resolvedPath = [System.IO.Path]::GetDirectoryName($resolvedPath)
    }
} else {
    $resolvedPath = ''
}
$resolvedPath

相关问题