두 가지 경로가 있습니다.
fred\frog
과
..\frag
다음과 같이 PowerShell에서 함께 조인 할 수 있습니다.
join-path 'fred\frog' '..\frag'
그것은 나에게 이것을 준다 :
fred\frog\..\frag
그러나 나는 그것을 원하지 않는다. 다음과 같이 이중 점이없는 정규화 된 경로를 원합니다.
fred\frag
어떻게 얻을 수 있습니까?
답변
당신의 조합을 사용할 수 있습니다 pwd, Join-Path그리고 [System.IO.Path]::GetFullPath완전한 확장 된 경로를 얻을 수 있습니다.
cd( Set-Location)는 프로세스의 현재 작업 디렉터리를 변경하지 않기 때문에 PowerShell 컨텍스트를 이해하지 못하는 .NET API에 상대 파일 이름을 전달하기 만하면 초기 작업을 기반으로하는 경로로 확인하는 것과 같은 의도하지 않은 부작용이 발생할 수 있습니다. 디렉터리 (현재 위치 아님).
당신이하는 일은 먼저 당신의 경로를 한정하는 것입니다.
Join-Path (Join-Path (pwd) fred\frog) '..\frag'
이것은 (내 현재 위치를 감안할 때) :
C:\WINDOWS\system32\fred\frog\..\frag
절대 기반을 사용하면 .NET API를 호출하는 것이 안전합니다 GetFullPath.
[System.IO.Path]::GetFullPath((Join-Path (Join-Path (pwd) fred\frog) '..\frag'))
완전한 경로와 ..제거 된 경로를 제공합니다 .
C:\WINDOWS\system32\fred\frag
그것은 개인적으로도 외부 스크립트에 의존하는 솔루션을 경멸합니다. Join-Path그리고 pwd( GetFullPath그냥 예쁘게 만드는 것입니다)에 의해 적절하게 해결되는 간단한 문제 입니다. 상대 부분 만 유지하고 싶다면 그냥 추가 .Substring((pwd).Path.Trim('\').Length + 1)하고 짜잔!
fred\frag
최신 정보
C:\엣지 케이스 를 지적 해 주신 @Dangph에게 감사드립니다 .
답변
resolve-path를 사용하여 .. \ frag를 전체 경로로 확장 할 수 있습니다.
PS > resolve-path ..\frag
Combine () 메서드를 사용하여 경로를 정규화하십시오.
[io.path]::Combine("fred\frog",(resolve-path ..\frag).path)
답변
Path.GetFullPath 를 사용할 수도 있지만 (Dan R의 답변과 마찬가지로) 전체 경로를 제공합니다. 사용법은 다음과 같습니다.
[IO.Path]::GetFullPath( "fred\frog\..\frag" )
또는 더 흥미롭게
[IO.Path]::GetFullPath( (join-path "fred\frog" "..\frag") )
둘 다 다음을 생성합니다 (현재 디렉토리가 D : \라고 가정).
D:\fred\frag
이 메소드는 fred 또는 frag가 실제로 존재하는지 여부를 판별하지 않습니다.
답변
받아 들여진 대답은 큰 도움이되었지만 절대 경로도 제대로 ‘정규화’하지 못했습니다. 절대 경로와 상대 경로를 모두 정규화하는 내 파생 작업 아래에서 찾으십시오.
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;
}
답변
PowerShell의 공급자 모델을 사용하면 PowerShell의 현재 경로가 Windows에서 프로세스의 작업 디렉터리라고 생각하는 것과 다를 수 있기 때문에 PowerShell이 아닌 경로 조작 기능 (예 : System.IO.Path의 기능)은 PowerShell에서 신뢰할 수 없습니다.
또한 이미 발견 한 것처럼 PowerShell의 Resolve-Path 및 Convert-Path cmdlet은 상대 경로 ( ‘..’s 포함)를 드라이브 한정 절대 경로로 변환하는 데 유용하지만 참조 된 경로가 존재하지 않으면 실패합니다.
다음의 매우 간단한 cmdlet은 존재하지 않는 경로에 대해 작동합니다. ‘fred’또는 ‘frag’파일 또는 폴더를 찾을 수없는 경우에도 ‘fred \ frog \ .. \ frag’를 ‘d : \ 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($_)
}
}
}
답변
이 라이브러리는 좋습니다 : NDepend.Helpers.FileDirectoryPath .
편집 : 이것은 내가 생각 해낸 것입니다.
[Reflection.Assembly]::LoadFrom("path\to\NDepend.Helpers.FileDirectoryPath.dll") | out-null
Function NormalizePath ($path)
{
if (-not $path.StartsWith('.\')) # FilePathRelative requires relative paths to begin with '.'
{
$path = ".\$path"
}
if ($path -eq '.\.') # FilePathRelative can't deal with this case
{
$result = '.'
}
else
{
$relPath = New-Object NDepend.Helpers.FileDirectoryPath.FilePathRelative($path)
$result = $relPath.Path
}
if ($result.StartsWith('.\')) # remove '.\'.
{
$result = $result.SubString(2)
}
$result
}
다음과 같이 호출하십시오.
> NormalizePath "fred\frog\..\frag"
fred\frag
이 스 니펫에는 DLL 경로가 필요합니다. 현재 실행중인 스크립트가 포함 된 폴더를 찾는 데 사용할 수있는 트릭이 있지만 제 경우에는 사용할 수있는 환경 변수가 있으므로 방금 사용했습니다.
답변
이것은 전체 경로를 제공합니다.
(gci 'fred\frog\..\frag').FullName
이것은 현재 디렉토리에 상대적인 경로를 제공합니다.
(gci 'fred\frog\..\frag').FullName.Replace((gl).Path + '\', '')
어떤 이유로 그들은 frag파일이 아닌 directory.
