Powershell:解决可能不存在的路径?

Eam*_*nne 50 powershell

我正在尝试处理一个文件列表,这些文件可能是也可能不是最新的,可能存在也可能不存在.在这样做时,我需要解析项目的完整路径,即使该项目可能使用相对路径指定.但是,Resolve-Path与不存在的文件一起使用时会出现打印和错误.

例如,什么是最简单的化解,干净的方式".\newdir\newfile.txt""C:\Current\Working\Directory\newdir\newfile.txt"使用PowerShell

请注意,System.IO.Path静态方法与进程的工作目录一起使用 - 这不是powershell的当前位置.

x0n*_*x0n 78

你要:

c:\path\exists\> $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath(".\nonexist\foo.txt")
Run Code Online (Sandbox Code Playgroud)

收益:

c:\path\exists\nonexists\foo.txt
Run Code Online (Sandbox Code Playgroud)

这样做的好处是可以使用PSPath,而不是本机文件系统路径.PSPAth可能不会将1-1映射到文件系统路径,例如,如果您安装具有多字母驱动器名称的psdrive.

-Oisin

  • OMG,`Resolve-Path` cmdlet如何没有标记也不测试该路径. (6认同)
  • @ x0n根据[Approved Verbs](https://msdn.microsoft.com/en-us/library/ms714428(v = vs.85).aspx)页面,所有Resolve的意思是,"映射一个简写表示更完整的代表资源." 它没有说明检查资源的存在. (3认同)
  • ps>[io.path]::GetFullPath("./somedir") 返回 "D:\bla-bla-folder\somedir" (2认同)

jos*_*hls 26

Resolve-Path失败是由于文件不存在,完全解决路径是从抛出Error对象访问.

您可以使用以下功能来修复Resolve-Path并使其按预期工作.

function Force-Resolve-Path {
    <#
    .SYNOPSIS
        Calls Resolve-Path but works for files that don't exist.
    .REMARKS
        From http://devhawk.net/blog/2010/1/22/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
}
Run Code Online (Sandbox Code Playgroud)

  • 恕我直言,迄今为止最好的答案 (3认同)

Kei*_*ill 14

我认为你走的是正确的道路.只需使用[Environment] :: CurrentDirectory设置.NET的进程当前目录的概念,例如:

[Environment]::CurrentDirectory = $pwd
[IO.Path]::GetFullPath(".\xyz")
Run Code Online (Sandbox Code Playgroud)

  • 好点子.当然,您可以首先获取.NET当前目录,然后将其设置为文件系统提供程序路径(不使用$ pwd),然后将当前目录重置为其原始值. (3认同)
  • 是的,但这有副作用,并且有一些令人讨厌的互操作,我想避免 - 我有点希望这是 powershell (毕竟是一种 shell 脚本语言)可以本地处理的东西。 . 无论如何,+1 是一个实际的选择! (2认同)
  • 它还存在一个问题,即 $pwd 实际上也可能不是文件系统上的真实路径;例如,如果您安装具有多字母驱动器名称的 psdrive。 (2认同)

Ron*_*rby 5

这样做的好处是无需设置CLR Environment的当前目录:

[IO.Path]::Combine($pwd,"non\existing\path")
Run Code Online (Sandbox Code Playgroud)

注意

这在功能上与x0n的答案不同.System.IO.Path.Combine仅组合字符串路径段.它的主要功能是让开发人员不必担心斜线.GetUnresolvedProviderPathFromPSPath将根据.'s和..' 来遍历相对于当前工作目录的输入路径.

  • 这并不是一个真正可行的解决方案。它假定 psdrive 与提供商后备存储的名称相同。您可以在 powershell 中有一个名为“stuff:\”的驱动器,该驱动器映射到“c:\”,例如,此解决方案将传递 psdrive 名称而不是 win32 名称,这会失败 (2认同)

Max*_*oro 5

Join-Path (Resolve-Path .) newdir\newfile.txt
Run Code Online (Sandbox Code Playgroud)

  • 仅当假设 'newdir' 是相对的时才有效。`Join-Path (Resolve-Path .) F:\thisuer\specified\absolutepath\inparameter` (4认同)