J'ai deux chemins:
fred\frog
et
..\frag
Je peux les joindre dans PowerShell comme ceci:
join-path 'fred\frog' '..\frag'
Cela me donne ceci:
fred\frog\..\frag
Mais je ne veux pas de ça. Je veux un chemin normalisé sans les doubles points, comme ceci:
fred\frag
Comment puis-je l'obtenir?
powershell
path
dan-gph
la source
la source
Réponses:
Vous pouvez utiliser une combinaison de
pwd
,Join-Path
et[System.IO.Path]::GetFullPath
d'obtenir un chemin dilatée complet.Étant donné que
cd
(Set-Location
) ne modifie pas le répertoire de travail actuel du processus, le simple fait de passer un nom de fichier relatif à une API .NET qui ne comprend pas le contexte PowerShell peut avoir des effets secondaires inattendus, tels que la résolution d'un chemin basé sur le travail initial répertoire (pas votre emplacement actuel).Ce que vous faites, c'est d'abord qualifier votre chemin:
Cela donne (étant donné ma position actuelle):
Avec une base absolue, il est sûr d'appeler l'API .NET
GetFullPath
:Ce qui vous donne le chemin complet et avec le
..
supprimé:Ce n'est pas compliqué non plus, personnellement, je dédaigne les solutions qui dépendent de scripts externes pour cela, c'est un problème simple résolu assez bien par
Join-Path
etpwd
(GetFullPath
c'est juste pour le rendre joli). Si vous ne souhaitez conserver que la partie relative , il vous suffit d'ajouter.Substring((pwd).Path.Trim('\').Length + 1)
et le tour est joué!METTRE À JOUR
Merci à @Dangph d'avoir souligné le
C:\
cas de bord.la source
cd c:\; "C:\fred\frag".Substring((pwd).Path.Length + 1)
. Ce n'est pas grave; juste quelque chose dont il faut être conscient.cd c:\; "C:\fred\frag".Substring((pwd).Path.Trim('\').Length + 1)
. Mais ça devient un peu long.Vous pouvez développer .. \ frag jusqu'à son chemin complet avec le chemin de résolution:
Essayez de normaliser le chemin en utilisant la méthode combine ():
la source
C:\Windows
vsC:\Windows\
le même chemin mais deux résultats différents[io.path]::Combine
sont inversés. Mieux encore, utilisez laJoin-Path
commande native PowerShell:Join-Path (Resolve-Path ..\frag).Path 'fred\frog'
notez également que, au moins à partir de PowerShell v3,Resolve-Path
prend désormais en charge le-Relative
commutateur pour la résolution d'un chemin relatif au dossier actuel. Comme mentionné,Resolve-Path
ne fonctionne qu'avec les chemins existants, contrairement à[IO.Path]::GetFullPath()
.Vous pouvez également utiliser Path.GetFullPath , bien que (comme avec la réponse de Dan R) cela vous donnera le chemin complet. L'utilisation serait la suivante:
ou plus intéressant
qui donnent tous deux ce qui suit (en supposant que votre répertoire actuel est D: \):
Notez que cette méthode ne tente pas de déterminer si fred ou frag existent réellement.
la source
[System.IO.Directory]::SetCurrentDirectory(((Get-Location -PSProvider FileSystem).ProviderPath))
[IO.Path]::GetFullPath()
contrairement au natif de PowerShellResolve-Path
, fonctionne également avec des chemins inexistants. Son inconvénient est la nécessité de synchroniser d'abord le dossier de travail de .NET avec celui de PS, comme le souligne @JasonMArcher.Join-Path
provoque une exception si vous faites référence à un lecteur qui n'existe pas.La réponse acceptée a été d'une grande aide, mais elle ne «normalise» pas correctement un chemin absolu aussi. Retrouvez ci-dessous mon travail dérivé qui normalise les chemins absolus et relatifs.
la source
[IO.Path]::GetFullPath()
ne détermine pas correctement le répertoire d'un nom de fichier simple.Toutes les fonctions de manipulation de chemin non PowerShell (telles que celles de System.IO.Path) ne seront pas fiables à partir de PowerShell car le modèle de fournisseur de PowerShell permet au chemin actuel de PowerShell de différer de ce que Windows pense être le répertoire de travail du processus.
De plus, comme vous l'avez peut-être déjà découvert, les applets de commande Resolve-Path et Convert-Path de PowerShell sont utiles pour convertir les chemins relatifs (ceux contenant des '..') en chemins absolus qualifiés par lecteur, mais ils échouent si le chemin référencé n'existe pas.
L'applet de commande très simple suivante devrait fonctionner pour les chemins inexistants. Il convertira 'fred \ frog \ .. \ frag' en 'd: \ fred \ frag' même si un fichier ou un dossier 'fred' ou 'frag' est introuvable (et que le lecteur PowerShell actuel est 'd:') .
la source
Get-AbsolutePath q:\foo\bar\..\baz
échoue même s'il s'agit d'un chemin valide. Eh bien, en fonction de votre définition d'un chemin valide. :-) FWIW, même le intégréTest-Path <path> -IsValid
échoue sur des chemins enracinés dans des lecteurs qui n'existent pas.HKLM:\SOFTWARE
est un chemin valide dans PowerShell, faisant référence à laSOFTWARE
clé dans la ruche de registre de l'ordinateur local. Mais pour savoir s'il est valide, il doit déterminer quelles sont les règles des chemins de registre.Cette bibliothèque est bonne: NDepend.Helpers.FileDirectoryPath .
EDIT: C'est ce que j'ai trouvé:
Appelez ça comme ça:
Notez que cet extrait de code nécessite le chemin d'accès à la DLL. Il existe une astuce que vous pouvez utiliser pour trouver le dossier contenant le script en cours d'exécution, mais dans mon cas, j'avais une variable d'environnement que je pourrais utiliser, alors je viens de l'utiliser.
la source
Cela donne le chemin complet:
Cela donne le chemin relatif au répertoire courant:
Pour une raison quelconque, ils ne fonctionnent que s'il
frag
s'agit d'un fichier, pas d'un fichierdirectory
.la source
Créez une fonction. Cette fonction normalisera un chemin qui n'existe pas sur votre système et n'ajoutera pas de lettres de lecteurs.
Ex:
Merci à Oliver Schadlich pour son aide dans le RegEx.
la source
somepaththing\.\filename.txt
car il conserve ce point uniqueSi le chemin comprend un qualificatif (lettre de lecteur), la réponse de x0n à Powershell: résoudre le chemin qui pourrait ne pas exister? normalisera le chemin. Si le chemin n'inclut pas le qualificatif, il sera toujours normalisé mais renverra le chemin d'accès complet relatif au répertoire courant, ce qui peut ne pas être ce que vous voulez.
la source
Si vous devez supprimer la partie .., vous pouvez utiliser un objet System.IO.DirectoryInfo. Utilisez 'fred \ frog .. \ frag' dans le constructeur. La propriété FullName vous donnera le nom de répertoire normalisé.
Le seul inconvénient est qu'il vous donnera le chemin complet (par exemple c: \ test \ fred \ frag).
la source
Les parties utiles des commentaires ici combinées de manière à unifier les chemins relatifs et absolus:
Certains échantillons:
production:
la source
Eh bien, une solution serait:
Attendez, peut-être ai-je mal compris la question. Dans votre exemple, frag est-il un sous-dossier de grenouille?
la source