2014-09-16 4 views
58

Wenn ich zwei Strings in einen Dateipfad kombinieren wollen, verwende ich join-path wie folgt aus:Wie verwende ich Join-Pfad, um mehr als zwei Zeichenfolgen in einen Dateipfad zu kombinieren?

$path = join-path C: "Program Files" 
write-host $path 

das druckt C:\Program Files". Wenn ich dies allerdings für mehr als zwei Strings tun:

$path = join-path C: "Program Files" "Microsoft Office" 
write-host $path 

Powershell wirft einen Fehler:

Join-Path : A positional parameter cannot be found that accepts argument 'Micro 
soft Office'. 
At D:\users\ma\my_script.ps1:1 char:18 
+ $path = join-path <<<< C: "Program Files" "Microsoft Office" 
    + CategoryInfo   : InvalidArgument: (:) [Join-Path], ParameterBindi 
    ngException 
    + FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell 
    .Commands.JoinPathCommand 

Ich habe versucht, ein String-Array mit:

[string[]] $pieces = "C:", "Program Files", "Microsoft Office" 
$path = join-path $pieces 
write-host $path 

aber Powershell fordert mich um den Childpath einzugeben (da ich das Argument -childpath nicht angegeben habe), z „Somepath“, und erstellt dann drei Dateien Pfade,

C:\somepath 
Program Files\somepath 
Microsoft Office\somepath 

was auch nicht richtig ist.

Antwort

103

Sie können die verwenden.NET Path-Klasse:

[io.path]::combine('c:\', 'foo', 'bar') 
+3

Sicherlich die prägnanteste Form, und behandelt Pfadtrennzeichen und nachfolgende/führende Schrägstriche auf Pfadfragmente ordnungsgemäß, die die aktuelle akzeptierte Antwort (grundlegende Zeichenfolge-Verkettung) nicht tut. –

+2

Für die Ausführung oben genannten Befehl in meiner Powershell ise bekommen diesen Fehler -Cann nicht finden eine Überladung für "Kombinieren" und die Anzahl der Argumente: "3". Bei Zeile: 1 Zeichen: 19 + [io.path] :: kombinieren <<<< ('c: \', 'foo', 'bar') + KategorieInfo: NotSpecified: (:) [], MethodException + FullyQualifiedErrorId: MethodCountCouldNotFindBest – Aamol

+0

@Aamol Welche CLR-Version wird ausgeführt ('$ PSVersionTable')? Funktioniert '[io.path] :: combine ([string []] ('c: \', 'foo', 'bar'))? – mtman

12

Join-Path ist nicht genau das, was Sie suchen. Es hat mehrere Anwendungen, aber nicht die, nach denen Sie suchen. Ein Beispiel aus Partying with Join-Path

Join-Path C:\hello,d:\goodbye,e:\hola,f:\adios world 
C:\hello\world 
d:\goodbye\world 
e:\hola\world 
f:\adios\world 

Sie sehen, dass es ein Array von Strings akzeptiert und es verkettet das Kind Zeichenfolge zu jedem Erstellen vollständigen Pfade. In Ihrem Beispiel $path = join-path C: "Program Files" "Microsoft Office". Sie erhalten den Fehler, da Sie 3 Positionsargumente sind vorbei und join-path akzeptiert nur 2. Was Sie suchen ist ein -join und ich konnte dies ein Missverständnis zu sein sehen. Betrachten Sie stattdessen diese mit Ihrem Beispiel:

"C:","Program Files","Microsoft Office" -join "\" 

-Join nimmt das Array von Elementen und verkettet sie mit \ in einem einzigen String.

C:\Program Files\Microsoft Office 

Minor Versuch einer Bergung

Ja, ich stimme zu, dass this answer besser ist, aber ich konnte immer noch funktionieren. Kommentare deuten darauf hin, dass es ein Problem mit Schrägstrichen geben könnte, damit Sie mit meiner Verkettungsansatzsweise fortfahren können.

"C:","\\Program Files\","Microsoft Office\" -join "\" -replace "(?!^\\)\\{2,}","\" 

Also, wenn es Probleme mit zusätzlichem schlitzen es so lange behandelt werden könnte, da sie nicht am Anfang des Strings sind (erlaubt UNC-Pfade). [io.path]::combine('c:\', 'foo', '\bar\') würde nicht wie erwartet funktionieren und meins würde dafür verantwortlich sein. Beide erfordern richtige Zeichenfolgen für die Eingabe, da Sie nicht alle Szenarien berücksichtigen können. Betrachten Sie beide Ansätze, aber ja, die andere höher bewertete Antwort ist knapper und ich wusste nicht einmal, dass sie existiert.

Außerdem würde darauf hinweisen, meine Antwort wird erklärt, wie, was der OP tut oben falsch war, einen Vorschlag für die Bereitstellung des Kernproblem zu lösen.

+2

Dies ist falsch, denn obwohl mehrere aufeinanderfolgende \ in Pfad funktioniert, ist es hässlich und kann möglicherweise Probleme verursachen. –

+0

@MikhailOrlov Können Sie ein mögliches Problem so beschreiben, dass es nur vermuten lässt, dass es passieren könnte? Hast du einen anderen Vorschlag? Ich frage, da ich kein Problem sehe. Wenn etwas nicht stimmt, möchte ich es ansprechen. – Matt

+2

Ich habe in letzter Zeit viel Code mit niedriger Qualität verarbeitet, Leute vergleichen Pfade nach String.Equals und analysieren Pfade mit String.Split ('\\'), ohne leere Zeichenfolgen zu entfernen. Ich kann mir nichts Bedrohlicheres vorstellen, meistens bin ich nur paranoid. Danke für deine Bearbeitung. –

56

Da Join-Path kann seinen Weg Wert geleitet werden, Sie können über die Pipeline mehrere Join-Path Aussagen zusammen:

Join-Path "C:" -ChildPath "Windows" | Join-Path -ChildPath "system32" | Join-Path -ChildPath "drivers" 

Es ist nicht so kurz und bündig, wie Sie es wahrscheinlich wie es sein, aber es ist voll Powershell und relativ einfach

+0

+1 da es über alle powershell 2,3,4 funktioniert, ist das Problem mit der [io.path] :: Combine API für .NET Framework 3,4 anders – Ram

7

zu lesen Wenn Sie sind immer noch mit 2,0 .Net dann [IO.Path]::Combine nicht params string[] Überlastung, die Sie mehr als zwei Teile müssen sich registrieren müssen, und Sie werden den Fehler nicht gefunden sehen ein Overl oad für "Combine" und die Anzahl der Argumente: "3".

Etwas weniger elegant, aber reine Powershell Lösung ist manuell Aggregat Pfad Teile:

join-path C: (join-path "Program Files" "Microsoft Office") 

oder

join-path (join-path C: "Program Files") "Microsoft Office" 
4

Hier ist etwas, das zu tun, was man sich wünschen kann, wenn ein String-Array mit für der ChildPath.

$path = "C:" 
@("Program Files", "Microsoft Office") | %{ $path = Join-Path $path $_ } 
Write-Host $path 

Welche

C:\Program Files\Microsoft Office 

Die einzige Einschränkung gibt, fand ich, dass der Anfangswert für $ Pfad einen Wert haben muss (kann nicht null oder leer sein).

Verwandte Themen