Eu tenho dois caminhos:
fred\frog
e
..\frag
Posso juntá-los no PowerShell assim:
join-path 'fred\frog' '..\frag'
Isso me dá isso:
fred\frog\..\frag
Mas eu não quero isso. Quero um caminho normalizado sem os pontos duplos, como este:
fred\frag
Como posso conseguir isso?
powershell
path
dan-gph
fonte
fonte
Respostas:
Você pode usar uma combinação de
pwd
,Join-Path
e[System.IO.Path]::GetFullPath
para obter um caminho expandido totalmente qualificado.Como
cd
(Set-Location
) não altera o diretório de trabalho atual do processo, simplesmente passar um nome de arquivo relativo a uma API .NET que não entende o contexto do PowerShell pode ter efeitos colaterais indesejados, como resolver para um caminho baseado no trabalho inicial diretório (não sua localização atual).O que você faz é primeiro qualificar seu caminho:
Isso produz (dada minha localização atual):
Com uma base absoluta, é seguro chamar a API .NET
GetFullPath
:O que fornece o caminho totalmente qualificado e com o
..
removido:Também não é complicado, pessoalmente, desprezo as soluções que para isso dependem de scripts externos, é um problema simples resolvido de forma bastante adequada por
Join-Path
epwd
(GetFullPath
serve apenas para torná-lo bonito). Se você quiser manter apenas a parte relativa , basta adicionar.Substring((pwd).Path.Trim('\').Length + 1)
e pronto!ATUALIZAR
Obrigado a @Dangph por apontar o
C:\
caso extremo.fonte
cd c:\; "C:\fred\frag".Substring((pwd).Path.Length + 1)
. Não é grande coisa; apenas algo para estar ciente.cd c:\; "C:\fred\frag".Substring((pwd).Path.Trim('\').Length + 1)
. Mas está ficando meio longo.Você pode expandir .. \ frag para seu caminho completo com resolve-path:
Tente normalizar o caminho usando o método combine ():
fonte
C:\Windows
contraC:\Windows\
o mesmo caminho, mas com dois resultados diferentes[io.path]::Combine
estão invertidos. Melhor ainda, use oJoin-Path
comando PowerShell nativo :Join-Path (Resolve-Path ..\frag).Path 'fred\frog'
Observe também que, pelo menos a partir do PowerShell v3,Resolve-Path
agora oferece suporte à-Relative
opção para resolver para um caminho relativo à pasta atual. Conforme mencionado,Resolve-Path
só funciona com caminhos existentes, ao contrário[IO.Path]::GetFullPath()
.Você também pode usar Path.GetFullPath , embora (como na resposta de Dan R) isso forneça o caminho completo. O uso seria o seguinte:
ou mais interessante
ambos produzem o seguinte (assumindo que seu diretório atual seja D: \):
Observe que este método não tenta determinar se fred ou frag realmente existem.
fonte
[System.IO.Directory]::SetCurrentDirectory(((Get-Location -PSProvider FileSystem).ProviderPath))
[IO.Path]::GetFullPath()
:, ao contrário do nativo do PowerShellResolve-Path
, funciona com caminhos inexistentes também. Sua desvantagem é a necessidade de sincronizar a pasta de trabalho do .NET com o PS 'primeiro, como @JasonMArcher aponta.Join-Path
causa uma exceção se estiver se referindo a uma unidade que não existe.A resposta aceita foi de grande ajuda, mas também não "normaliza" adequadamente um caminho absoluto. Encontre abaixo meu trabalho derivado que normaliza os caminhos absolutos e relativos.
fonte
[IO.Path]::GetFullPath()
, não determina corretamente o diretório para um nome de arquivo simples.Quaisquer funções de manipulação de caminho não PowerShell (como aquelas em System.IO.Path) não serão confiáveis do PowerShell porque o modelo de provedor do PowerShell permite que o caminho atual do PowerShell seja diferente do que o Windows pensa que é o diretório de trabalho do processo.
Além disso, como você já deve ter descoberto, os cmdlets Resolve-Path e Convert-Path do PowerShell são úteis para converter caminhos relativos (aqueles contendo '..' s) em caminhos absolutos qualificados de unidade, mas eles falham se o caminho referenciado não existir.
O seguinte cmdlet muito simples deve funcionar para caminhos não existentes. Ele converterá 'fred \ frog \ .. \ frag' em 'd: \ fred \ frag' mesmo se um arquivo ou pasta 'fred' ou 'frag' não puder ser encontrado (e a unidade PowerShell atual for 'd:') .
fonte
Get-AbsolutePath q:\foo\bar\..\baz
falha, embora seja um caminho válido. Bem, dependendo da sua definição de um caminho válido. :-) FWIW, mesmo o embutidoTest-Path <path> -IsValid
falha em caminhos enraizados em drives que não existem.HKLM:\SOFTWARE
é um caminho válido no PowerShell, referindo-se àSOFTWARE
chave na seção de registro da Máquina Local. Mas para descobrir se ele é válido, ele precisa descobrir quais são as regras para caminhos de registro.Esta biblioteca é boa: NDepend.Helpers.FileDirectoryPath .
EDIT: Isto é o que eu inventei:
Chame assim:
Observe que este trecho requer o caminho para a DLL. Existe um truque que você pode usar para encontrar a pasta que contém o script em execução no momento, mas no meu caso, eu tinha uma variável de ambiente que poderia usar, então acabei de usá-la.
fonte
Isso fornece o caminho completo:
Isso fornece o caminho relativo ao diretório atual:
Por algum motivo, eles só funcionam se
frag
for um arquivo, não umdirectory
.fonte
Crie uma função. Esta função normalizará um caminho que não existe em seu sistema e também não adicionará letras de unidade.
Ex:
Agradeço a Oliver Schadlich pela ajuda no RegEx.
fonte
somepaththing\.\filename.txt
, pois mantém aquele único pontoSe o caminho incluir um qualificador (letra da unidade), a resposta de x0n para o Powershell: resolver caminho que pode não existir? irá normalizar o caminho. Se o caminho não incluir o qualificador, ele ainda será normalizado, mas retornará o caminho totalmente qualificado relativo ao diretório atual, que pode não ser o que você deseja.
fonte
Se você precisar se livrar da parte .., você pode usar um objeto System.IO.DirectoryInfo. Use 'fred \ frog .. \ frag' no construtor. A propriedade FullName fornecerá o nome do diretório normalizado.
A única desvantagem é que ele fornecerá o caminho completo (por exemplo, c: \ test \ fred \ frag).
fonte
As partes convenientes dos comentários aqui combinadas de modo que unificam os caminhos relativos e absolutos:
Algumas amostras:
resultado:
fonte
Bem, uma maneira seria:
Espere, talvez eu tenha entendido mal a pergunta. No seu exemplo, frag é uma subpasta de sapo?
fonte