Ich habe zwei Wege:
fred\frog
und
..\frag
Ich kann sie in PowerShell folgendermaßen zusammenfügen:
join-path 'fred\frog' '..\frag'
Das gibt mir folgendes:
fred\frog\..\frag
Aber das will ich nicht. Ich möchte einen normalisierten Pfad ohne die doppelten Punkte, wie folgt:
fred\frag
Wie kann ich das bekommen?
powershell
path
dan-gph
quelle
quelle
Antworten:
Sie können eine Kombination von verwenden
pwd
,Join-Path
und[System.IO.Path]::GetFullPath
einen vollständig qualifizierten gespreizten Weg zu bekommen.Da
cd
(Set-Location
) das aktuelle Arbeitsverzeichnis des Prozesses nicht ändert, kann die einfache Übergabe eines relativen Dateinamens an eine .NET-API, die den PowerShell-Kontext nicht versteht, unbeabsichtigte Nebenwirkungen haben, z. B. das Auflösen in einen Pfad, der auf der anfänglichen Arbeit basiert Verzeichnis (nicht Ihr aktueller Standort).Was Sie tun, ist, dass Sie zuerst Ihren Weg qualifizieren:
Dies ergibt (angesichts meines aktuellen Standorts):
Mit einer absoluten Basis ist es sicher, die .NET-API aufzurufen
GetFullPath
:Welches gibt Ihnen den voll qualifizierten Weg und mit dem
..
entfernten:Es ist auch nicht kompliziert, persönlich, ich verachte die Lösungen, die von externen Skripten abhängen, es ist ein einfaches Problem, das ziemlich treffend durch
Join-Path
und gelöst wirdpwd
(GetFullPath
nur um es hübsch zu machen). Wenn Sie nur den relativen Teil behalten möchten, fügen Sie einfach hinzu.Substring((pwd).Path.Trim('\').Length + 1)
und voila!AKTUALISIEREN
Vielen Dank an @Dangph für den Hinweis auf den Randfall
C:\
.quelle
cd c:\; "C:\fred\frag".Substring((pwd).Path.Length + 1)
. Es ist keine große Sache; nur etwas zu beachten.cd c:\; "C:\fred\frag".Substring((pwd).Path.Trim('\').Length + 1)
. Es wird allerdings etwas lang.Sie können .. \ frag mit dem Auflösungspfad auf den vollständigen Pfad erweitern:
Versuchen Sie, den Pfad mit der Methode comb () zu normalisieren:
quelle
C:\Windows
gegenC:\Windows\
denselben Pfad ist, aber zwei unterschiedliche Ergebnisse[io.path]::Combine
sind umgekehrt. Verwenden Sie noch besser den nativenJoin-Path
PowerShell-Befehl:Join-Path (Resolve-Path ..\frag).Path 'fred\frog'
Beachten Sie außerdem, dass zumindest ab PowerShell v3Resolve-Path
jetzt der-Relative
Schalter zum Auflösen in einen Pfad relativ zum aktuellen Ordner unterstützt wird. Wie bereits erwähnt,Resolve-Path
funktioniert im Gegensatz dazu nur mit vorhandenen Pfaden[IO.Path]::GetFullPath()
.Sie können auch Path.GetFullPath verwenden , obwohl dies (wie bei der Antwort von Dan R) den gesamten Pfad angibt . Die Verwendung wäre wie folgt:
oder interessanter
Beide ergeben Folgendes (vorausgesetzt, Ihr aktuelles Verzeichnis ist D: \):
Beachten Sie, dass diese Methode nicht versucht festzustellen, ob Fred oder Frag tatsächlich vorhanden sind.
quelle
[System.IO.Directory]::SetCurrentDirectory(((Get-Location -PSProvider FileSystem).ProviderPath))
[IO.Path]::GetFullPath()
auszudrücken : Im Gegensatz zu PowerShellResolve-Path
funktioniert nativ auch mit nicht vorhandenen Pfaden. Der Nachteil ist, dass der Arbeitsordner von .NET zuerst mit dem von PS synchronisiert werden muss, wie @JasonMArcher hervorhebt.Join-Path
verursacht eine Ausnahme, wenn auf ein Laufwerk verwiesen wird, das nicht vorhanden ist.Die akzeptierte Antwort war eine große Hilfe, aber sie "normalisiert" auch einen absoluten Pfad nicht richtig. Finden Sie unten meine abgeleitete Arbeit, die sowohl absolute als auch relative Pfade normalisiert.
quelle
[IO.Path]::GetFullPath()
wird das Verzeichnis für einen einfachen Dateinamen nicht korrekt ermittelt.Alle Funktionen zur Manipulation von Nicht-PowerShell-Pfaden (z. B. in System.IO.Path) sind in PowerShell nicht zuverlässig, da das PowerShell-Anbietermodell es ermöglicht, dass der aktuelle Pfad von PowerShell von dem abweicht, was Windows für das Arbeitsverzeichnis des Prozesses hält.
Wie Sie vielleicht bereits festgestellt haben, sind die Cmdlets Resolve-Path und Convert-Path von PowerShell nützlich, um relative Pfade (solche mit '..') in Laufwerk-qualifizierte absolute Pfade zu konvertieren. Sie schlagen jedoch fehl, wenn der angegebene Pfad nicht vorhanden ist.
Das folgende sehr einfache Cmdlet sollte für nicht vorhandene Pfade funktionieren. Es konvertiert 'fred \ frog \ .. \ frag' in 'd: \ fred \ frag', auch wenn eine 'fred'- oder' frag'-Datei oder ein Ordner nicht gefunden werden kann (und das aktuelle PowerShell-Laufwerk 'd:' ist). .
quelle
Get-AbsolutePath q:\foo\bar\..\baz
schlägt fehl, obwohl es sich um einen gültigen Pfad handelt. Nun, abhängig von Ihrer Definition eines gültigen Pfades. :-) FWIW, sogar die integrierte FunktionTest-Path <path> -IsValid
schlägt auf Pfaden fehl, die auf nicht vorhandenen Laufwerken basieren .HKLM:\SOFTWARE
beispielsweise ein gültiger Pfad in PowerShell, der auf denSOFTWARE
Schlüssel in der Registrierungsstruktur des lokalen Computers verweist . Um herauszufinden, ob es gültig ist, müssen die Regeln für Registrierungspfade ermittelt werden.Diese Bibliothek ist gut: NDepend.Helpers.FileDirectoryPath .
EDIT: Das habe ich mir ausgedacht :
Nennen Sie es so:
Beachten Sie, dass für dieses Snippet der Pfad zur DLL erforderlich ist. Es gibt einen Trick, mit dem Sie den Ordner finden können, der das aktuell ausgeführte Skript enthält, aber in meinem Fall hatte ich eine Umgebungsvariable, die ich verwenden konnte, also habe ich diese einfach verwendet.
quelle
Dies gibt den vollständigen Weg:
Dies gibt den Pfad relativ zum aktuellen Verzeichnis an:
Aus irgendeinem Grund funktionieren sie nur, wenn
frag
es sich um eine Datei handelt, nicht um einedirectory
.quelle
Erstellen Sie eine Funktion. Diese Funktion normalisiert einen Pfad, der auf Ihrem System nicht vorhanden ist, und fügt keine Laufwerksbuchstaben hinzu.
Ex:
Vielen Dank an Oliver Schadlich für die Hilfe bei der RegEx.
quelle
somepaththing\.\filename.txt
da dieser einzelne Punkt beibehalten wirdWenn der Pfad ein Qualifikationsmerkmal (Laufwerksbuchstabe) enthält, lautet die Antwort von x0n auf Powershell: Pfad auflösen, der möglicherweise nicht vorhanden ist? normalisiert den Pfad. Wenn der Pfad das Qualifikationsmerkmal nicht enthält, wird er weiterhin normalisiert, gibt jedoch den vollständig qualifizierten Pfad relativ zum aktuellen Verzeichnis zurück, was möglicherweise nicht Ihren Wünschen entspricht.
quelle
Wenn Sie den Teil .. entfernen müssen, können Sie ein System.IO.DirectoryInfo-Objekt verwenden. Verwenden Sie im Konstruktor 'fred \ frog .. \ frag'. Die FullName-Eigenschaft gibt Ihnen den normalisierten Verzeichnisnamen.
Der einzige Nachteil ist, dass Sie den gesamten Pfad erhalten (z. B. c: \ test \ fred \ frag).
quelle
Die zweckmäßigen Teile der Kommentare hier wurden so kombiniert, dass sie relative und absolute Pfade vereinen:
Einige Beispiele:
Ausgabe:
quelle
Ein Weg wäre:
Warten Sie, vielleicht verstehe ich die Frage falsch. Ist frag in Ihrem Beispiel ein Unterordner von Frosch?
quelle