我有两条路:
fred\frog
Run Code Online (Sandbox Code Playgroud)
和
..\frag
Run Code Online (Sandbox Code Playgroud)
我可以在PowerShell中将它们连接在一起,如下所示:
join-path 'fred\frog' '..\frag'
Run Code Online (Sandbox Code Playgroud)
这给了我这个:
fred\frog\..\frag
Run Code Online (Sandbox Code Playgroud)
但我不希望这样.我想要一个没有双点的标准化路径,如下所示:
fred\frag
Run Code Online (Sandbox Code Playgroud)
我怎么能得到它?
Sha*_*evy 99
您可以使用resolve-path将..\frag扩展为其完整路径:
PS > resolve-path ..\frag
Run Code Online (Sandbox Code Playgroud)
尝试使用combine()方法规范化路径:
[io.path]::Combine("fred\frog",(resolve-path ..\frag).path)
Run Code Online (Sandbox Code Playgroud)
Joh*_*ren 77
您可以使用组合pwd,Join-Path并[System.IO.Path]::GetFullPath获得完全限定的扩展路径.
由于cd(Set-Location)不会更改进程当前工作目录,只需将相对文件名传递给不能理解PowerShell上下文的.NET API,就会产生意想不到的副作用,例如根据初始工作解析路径目录(不是您当前的位置).
你做的是你首先确定你的道路:
Join-Path (Join-Path (pwd) fred\frog) '..\frag'
Run Code Online (Sandbox Code Playgroud)
这会产生(给定我当前的位置):
C:\WINDOWS\system32\fred\frog\..\frag
Run Code Online (Sandbox Code Playgroud)
使用绝对库,可以安全地调用.NET API GetFullPath:
[System.IO.Path]::GetFullPath((Join-Path (Join-Path (pwd) fred\frog) '..\frag'))
Run Code Online (Sandbox Code Playgroud)
这为您提供了完全限定的路径并..删除了:
C:\WINDOWS\system32\fred\frag
Run Code Online (Sandbox Code Playgroud)
它也不复杂,我个人不屑依赖于这个外部脚本的解决方案,这是要解决相当贴切简单的问题,Join-Path和pwd(GetFullPath只是让它漂亮).如果你只想保留相关部分,你只需添加.Substring((pwd).Path.Trim('\').Length + 1)并瞧!
fred\frag
Run Code Online (Sandbox Code Playgroud)
感谢@Dangph指出C:\边缘情况.
Cha*_*lie 25
您也可以使用Path.GetFullPath,尽管(与Dan R的答案一样),这将为您提供整个路径.用法如下:
[IO.Path]::GetFullPath( "fred\frog\..\frag" )
Run Code Online (Sandbox Code Playgroud)
或者更有趣的是
[IO.Path]::GetFullPath( (join-path "fred\frog" "..\frag") )
Run Code Online (Sandbox Code Playgroud)
两者都产生以下结果(假设您当前的目录是D:\):
D:\fred\frag
Run Code Online (Sandbox Code Playgroud)
请注意,此方法不会尝试确定fred或frag是否实际存在.
小智 18
接受的答案是一个很大的帮助,但它也没有正确地"正常化"绝对路径.在下面找到我的衍生作品,它规范了绝对和相对路径.
function Get-AbsolutePath ($Path)
{
# System.IO.Path.Combine has two properties making it necesarry here:
# 1) correctly deals with situations where $Path (the second term) is an absolute path
# 2) correctly deals with situations where $Path (the second term) is relative
# (join-path) commandlet does not have this first property
$Path = [System.IO.Path]::Combine( ((pwd).Path), ($Path) );
# this piece strips out any relative path modifiers like '..' and '.'
$Path = [System.IO.Path]::GetFullPath($Path);
return $Path;
}
Run Code Online (Sandbox Code Playgroud)
Jas*_*ome 10
任何非PowerShell路径操作函数(例如System.IO.Path中的函数)都不可靠来自PowerShell,因为PowerShell的提供程序模型允许PowerShell的当前路径与Windows认为该进程的工作目录不同.
此外,正如您可能已经发现的那样,PowerShell的Resolve-Path和Convert-Path cmdlet对于将相对路径(包含'..'的路径)转换为驱动限定的绝对路径非常有用,但如果引用的路径不存在则它们会失败.
以下非常简单的cmdlet应适用于不存在的路径.它会将'fred\frog\..\frag'转换为'd:\ fred\frag',即使找不到'fred'或'frag'文件或文件夹(并且当前的PowerShell驱动器是'd:') .
function Get-AbsolutePath {
[CmdletBinding()]
param (
[Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
[string[]]
$Path
)
process {
$Path | ForEach-Object {
$PSCmdlet.SessionState.Path.GetUnresolvedProviderPathFromPSPath($_)
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果路径包含限定符(驱动器号),则x0n 对 Powershell 的回答:解析可能不存在的路径?将规范化路径。如果路径不包含限定符,它仍然会被规范化,但会返回相对于当前目录的完全限定路径,这可能不是您想要的。
$p = 'X:\fred\frog\..\frag'
$ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($p)
X:\fred\frag
$p = '\fred\frog\..\frag'
$ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($p)
C:\fred\frag
$p = 'fred\frog\..\frag'
$ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($p)
C:\Users\WileCau\fred\frag
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
76851 次 |
| 最近记录: |