我想将路径转换为PowerShell脚本中的相对路径。 如何使用PowerShell执行此操作?
例如:
Path to convert: c:\documents\mynicefiles\afile.txt
Reference path: c:\documents
Result: mynicefiles\afile.txt
和
Path to convert: c:\documents\myproject1\afile.txt
Reference path: c:\documents\myproject2
Result: ..\myproject1\afile.txt
答案 0 :(得分:50)
我找到了内置的内容,Resolve-Path:
Resolve-Path -Relative
返回相对于当前位置的路径。一个简单的用法:
$root = "C:\Users\Dave\"
$current = "C:\Users\Dave\Documents\"
$tmp = Get-Location
Set-Location $root
Resolve-Path -relative $current
Set-Location $tmp
答案 1 :(得分:2)
使用内置的System.IO.Path.GetRelativePath比接受的答案更简单:
[System.IO.Path]::GetRelativePath($relativeTo, $path)
答案 2 :(得分:0)
一种快速简便的方法是:
$current -replace [regex]::Escape($root), '.'
或者如果您想要从当前实际位置开始的相对路径
$path -replace [regex]::Escape((pwd).Path), '.'
这假定您的所有路径均有效。
答案 3 :(得分:0)
here是一个很好的答案,但它会更改当前目录(它会还原),但是如果您确实需要隔离该过程,则下面的代码示例可以提供帮助。只是在一个新的PowerShell实例中,它做同样的事情。
function Get-RelativePath($path, $relativeTo) {
$powershell = (Get-Process -PID $PID | Get-Item)
if ([string]::IsNullOrEmpty($powershell)) {
$powershell = "powershell.exe"
}
& $powershell -NoProfile -NonInteractive -ExecutionPolicy Unrestricted -Command "& { Set-Location `"$relativeTo`"; Resolve-Path `"$path`" -Relative}"
}
这确实很慢,除非您绝对必须使用此版本,否则您应该使用其他版本。
答案 4 :(得分:0)
有时我有多个“根”,我想从中生成相对的文件路径。我发现Resolve-Path -Relative
在这种情况下不可用。更改全局设置(当前位置)以生成相对文件路径似乎容易出错,并且(如果您正在编写并行代码)可能不是线程安全的。
以下内容应在Powershell和Powershell Core的早期或最新版本中起作用,即使在临时状态下也不会更改您的当前目录,并且与操作系统无关并且是线程安全的。
它没有解决OP中的第二个示例(根据需要插入..
。)
function Get-RelativePath {
param($path, $relativeTo)
# strip trailing slash
$relativeTo = Join-Path `
(Split-Path -Parent $relativeTo) `
(Split-Path -Leaf $relativeTo)
$relPath = Split-Path -Leaf $path
$path = Split-Path -Parent $path
do {
$leaf = Split-Path -Leaf $path
$relPath = Join-Path $leaf $relPath
$path = Split-Path -Parent $path
} until (($path -eq $relativeTo) -Or ($path.Length -eq 0))
$relPath
}
一个例子:
PS> $configRoot = 'C:\Users\P799634t\code\RMP\v2\AWD'
PS> $queryPath = 'C:\Users\P799634t\code\RMP\v2\AWD\config_queries\LOAD_UNQ_QUEUE_QUERY2.sql'
PS> Write-Host (Get-RelativePath $queryPath $configRoot)
config_queries\LOAD_UNQ_QUEUE_QUERY2.sql
当一个文件路径不是另一文件路径的子路径时,它的行为合理:
PS> $root = 'C:\Users\P799634t\code\RMP\v2\AWD'
PS> $notRelated = 'E:\path\to\origami'
PS> Write-Host (Get-RelativePath $notRelated $root)
E:\path\to\origami
答案 5 :(得分:-3)
这是另一种方法
$pathToConvert1 = "c:\documents\mynicefiles\afile.txt"
$referencePath1 = "c:\documents"
$result1 = $pathToConvert1.Substring($referencePath1.Length + 1)
#$result1: mynicefiles\afile.txt
和
$pathToConvert2 = "c:\documents\myproject1\afile.txt"
#$referencePath2 = "c:\documents\myproject2"
$result2 = "..\myproject" + [regex]::Replace($pathToConvert2 , ".*\d+", '')
#$result2: ..\myproject\afile.txt
注意:在第二种情况下,没有使用ref路径。