接受路径作为文字路径,相对路径或相对于脚本根目录

时间:2019-10-31 13:47:36

标签: powershell path

当前,我们在检索文件信息时涉及这三种情况:

  • 文字路径
  • 相对于脚本根目录的相对路径
  • 相对于当前工作目录的相对路径

为涵盖这3种情况,我们创建了以下函数:

Function Get-FilePathItemHC {
    Param (
        [Parameter(Mandatory)]
        [String]$Path
    )

    $Params = @(
        @{
            # Path relative to the script root
            LiteralPath = Join-Path -Path $PSScriptRoot -ChildPath $Path
        }
        @{
            # Literal or path relative to the present work directory
            Path = $Path
        }
    )

    $Item = $null

    foreach ($P in $Params) {
        if ($Item = Get-Item @P -ErrorAction Ignore) {
            $Item
            Break
        }
    }

    if (-not $Item) {
        throw "Cannot find path '$Path' because it does not exist."
    }
}

这是正确的做法吗?看来我们在这里重新发明轮子。

1 个答案:

答案 0 :(得分:1)

为您的-Path参数设置一个System.IO.FileInfo对象,然后传入一个相对路径作为参数。文件对象将使用相对路径或完整路径进行解析,然后您可以使用$path.FullName来引用文件的完整路径。

Function Get-FilePathItemHC {
    Param (
        [Parameter(Mandatory)]
        [ValidateScript({ $_.Exists })]
        [System.IO.FileInfo]$Path
    )

    # The ValidateScript attribute makes sure the file you passed in exists
    # so your validation code no longer is required
}

如果要同时处理目录和文件,则在这种情况下,您将需要具有两个单独的变量,因为目录路径将成为System.IO.DirectoryInfo对象,但是可以使参数互斥:

Function Get-FilePathItemHC {
Param (
    [Parameter(Mandatory=$true, ParameterSetName="FilePath")]
    [ValidateScript({ $_.Exists })]
    [System.IO.FileInfo]$FilePath,
    [Parameter(Mandatory=$true, ParameterSetName="DirectoryPath")]
    [ValidateScript({ $_.Exists })]
    [System.IO.DirectoryInfo]$DirectoryPath
)

  $Path = $FilePath
  if( $DirectoryPath ) {
    $Path = $DirectoryPath
  }

  # The ValidateScript attribute makes sure the file you passed in exists
  # so your validation code no longer is required
}

Get-FilePathItemHC -Path .\path\to\file.txt

$PSScriptRoot

获取相对路径

如果您已经拥有文件的完整路径,我不确定为什么需要相对于$PSScriptRoot的路径,但是在获取System.IO.FileInfoSystem.IO.DirectoryInfo对象之后,您可以使用Resolve-Path中的$PSScriptRoot从该目录获取相对路径:

$file = Get-FilePathItemHC -Path .\path\to\file.txt
Push-Location $PSScriptRoot
$relativeFromScriptRootPath = Resolve-Path -Relative $file
Pop-Location

Push-LocationPop-Location将位置视为堆栈。 push操作会设置一个新位置并将其添加到堆栈中,而pop操作会从堆栈中删除最后添加的位置,并将您放置在下一个最近的位置。如果您熟悉的话,在Linux上的工作原理类似于cd -

Resolve-Path将返回文件路径,而-Relative开关将返回相对于当前目录的路径。您无法传递替代目录来解析,这就是为什么我们更改了运行该目录的原因。