Powershell:解决可能不存在的path?
我试图处理可能或可能不是最新的,可能存在或可能不存在的文件列表。 这样做,我需要解决一个项目的完整path,即使该项目可能指定相对path。 但是,与不存在的文件一起使用时, Resolve-Path
打印并显示错误。
例如, 在Powershell "C:\Current\Working\Directory\newdir\newfile.txt"
".\newdir\newfile.txt"
parsing为"C:\Current\Working\Directory\newdir\newfile.txt"
的最简单,最简单的方法是什么?
请注意, System.IO.Path
的静态方法与进程的工作目录一起使用 – 这不是powershell的当前位置。
你要:
c:\path\exists\> $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath(".\nonexist\foo.txt")
收益:
c:\path\exists\nonexists\foo.txt
这具有使用PSPath而不是本地文件系统path的优点。 PSPAth可能无法将1-1映射到文件系统path,例如,如果使用多字母驱动器名称装入psdrive。
-Oisin
当Resolve-Path
由于文件不存在而失败时,可以从抛出的错误对象访问完全parsing的path。
你可以使用像下面这样的函数来修复Resolve-Path
并使它像你期望的那样工作。
function Force-Resolve-Path { <# .SYNOPSIS Calls Resolve-Path but works for files that don't exist. .REMARKS From http://devhawk.net/2010/01/21/fixing-powershells-busted-resolve-path-cmdlet/ #> param ( [string] $FileName ) $FileName = Resolve-Path $FileName -ErrorAction SilentlyContinue ` -ErrorVariable _frperror if (-not($FileName)) { $FileName = $_frperror[0].TargetObject } return $FileName }
我认为你在正确的道路上。 只需使用[Environment] :: CurrentDirectory来设置.NET的进程当前目录的概念,例如:
[Environment]::CurrentDirectory = $pwd [IO.Path]::GetFullPath(".\xyz")
这具有不需要设置CLR环境的当前目录的优点:
[IO.Path]::Combine($pwd,"non\existing\path")
注意
这在function上不等同于x0n的答案 。 System.IO.Path.Combine
仅组合stringpath段。 它的主要function是让开发人员不必担心斜杠。 GetUnresolvedProviderPathFromPSPath
将遍历相对于当前工作目录的inputpath,根据.
和..
的。
我发现以下工作得很好。
$workingDirectory = Convert-Path (Resolve-Path -path ".") $newFile = "newDir\newFile.txt" Do-Something-With "$workingDirectory\$newFile"
Convert-Path可以用来获取string的path,虽然情况并非总是如此。 有关更多详细信息,请参阅COnvert-Path上的此条目。
您可以将-errorAction设置为“SilentlyContinue”并使用Resolve-Path
5 > (Resolve-Path .\AllFilerData.xml -ea 0).Path C:\Users\Andy.Schneider\Documents\WindowsPowerShell\Scripts\AllFilerData.xml 6 > (Resolve-Path .\DoesNotExist -ea 0).Path 7 >
在parsing之前检查文件是否存在:
if(Test-Path .\newdir\newfile.txt) { (Resolve-Path .\newdir\newfile.txt).Path }
function Get-FullName() { [CmdletBinding()] Param( [Parameter(ValueFromPipeline = $True)] [object[]] $Path ) Begin{ $Path = @($Path); } Process{ foreach($p in $Path) { if($p -eq $null -or $p -match '^\s*$'){$p = [IO.Path]::GetFullPath(".");} elseif($p -is [System.IO.FileInfo]){$p = $p.FullName;} else{$p = [IO.Path]::GetFullPath($p);} $p; } } }
这里有一个可以接受的答案,但是这个答案非常冗长,还有一个更简单的select。
在任何最新版本的Powershell中,都可以使用Test-Path -IsValid -Path 'C:\Probably Fake\Path.txt'
这只是validationpath中没有非法字符,并且path可以用来存储文件。 如果目标不存在, Test-Path
将不会在意这个实例 – 它只被要求testing提供的path是否可能有效。
Join-Path (Resolve-Path .) newdir\newfile.txt