2014-09-16 8 views
58

Jeśli chcesz połączyć dwa ciągi do ścieżki pliku, używam join-path tak:Jak używać łączenia ścieżek, aby połączyć więcej niż dwa ciągi w ścieżkę pliku?

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

która drukuje C:\Program Files". Jeśli chcę to zrobić dla więcej niż dwóch ciągów jednak:

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

PowerShell zgłasza błąd:

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 

Próbowałem za pomocą tablicy ciągów:

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

ale PowerShell skłania mnie aby wprowadzić ścieżkę potomną (ponieważ nie podałem argumentu -childpath), np. "somepath", a następnie tworzy trzy ścieżki plików, które również nie są poprawne.

Odpowiedz

103

Możesz użyć.NET klasy Ścieżka:

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

Z pewnością jest to najbardziej zwięzła forma i obsługuje separatory ścieżek i końcowe/końcowe ukośniki na fragmentach ścieżek, których nie akceptuje aktualnie zaakceptowana odpowiedź (podstawowa konkatenacja łańcuchów). –

+2

Za wykonanie powyższego polecenia w moim pakiecie uprawnień otrzymuję ten błąd - nie można znaleźć przeciążenia dla "Połącz" i liczby argumentów: "3". W linii: 1 znak: 19 + [io.path] :: połącz <<<< ('c: \', 'foo', 'bar') + CategoryInfo: NotSpecified: (:) [], MethodException + FullyQualifiedErrorId: MethodCountCouldNotFindBest – Aamol

+0

@Aamol Jakiej wersji CLR używasz ('$ PSVersionTable')? Czy '[oktath] :: combine ([string []] ('c: \', 'foo', 'bar'))' działa? – mtman

12

Join-Path nie jest dokładnie tym, czego szukasz. Ma wiele zastosowań, ale nie ten, którego szukasz. Przykład z 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 

Zobaczysz, że przyjmuje tablicę ciągów i Łączy ciąg dziecko do siebie tworząc pełnych ścieżek. W twoim przykładzie $path = join-path C: "Program Files" "Microsoft Office". Otrzymujesz błąd, ponieważ przekazujesz 3 argumenty pozycyjne i join-path akceptuje tylko 2. To, czego szukasz, to -join i mogłem zobaczyć, że jest to nieporozumienie. Zastanów się zamiast tego z przykładu:

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

-Join wykonuje szereg elementów i łączy je z \ w jeden ciąg.

C:\Program Files\Microsoft Office 

Minor próba uratowania

Tak, zgadzam się, że jest lepiej, ale this answer kopalnia mogła nadal działać. Komentarze sugerują, że może występować problem z ukośnikami, więc aby zachować moje podejście do konkatenacji, możesz to zrobić również.

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

Więc jeśli istnieją problemy z Dodatkowym tnie mógłby być traktowany tak długo jak nie są one na początku łańcucha (umożliwia ścieżek UNC). [io.path]::combine('c:\', 'foo', '\bar\') nie działałby zgodnie z oczekiwaniami, a mój mógłby to wyjaśnić. Oba wymagają odpowiednich ciągów danych wejściowych, ponieważ nie można uwzględnić wszystkich scenariuszy. Rozważ oba podejścia, ale tak, druga, wyżej oceniona odpowiedź jest bardziej zwięzła i nawet nie wiedziałam, że istnieje.

Chciałbym również podkreślić, że moja odpowiedź wyjaśnia, w jaki sposób działania PO były niewłaściwe, a ponadto zawierały sugestię rozwiązania podstawowego problemu.

+2

Jest to niepoprawne, ponieważ pomimo tego, że wiele kolejnych \ w ścieżce działa, jest to brzydkie i może powodować potencjalne problemy. –

+0

@MikhailOrlov Czy możesz opisać potencjalny problem, który miał sugerować, że może się zdarzyć? Czy masz kolejną sugestię? Pytam, bo nie widzę problemu. Jeśli coś jest nie tak, chciałbym się do tego odnieść. – Matt

+2

Ostatnio obsługiwałem wiele niską jakość kodu, ludzie porównują ścieżki według String.Equals i analizują ścieżki za pomocą String.Split ('\\') bez usuwania pustych ciągów. Nie mogę wymyślić nic bardziej niebezpiecznego w skutkach, głównie jestem po prostu paranoikiem. Dziękuję za twoją edycję. –

56

Od Join-Path można rurami swoją wartość ścieżki, wy can oświadczenia stwardnienie rura Join-Path razem:

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

To nie jest tak lakoniczne, jak to prawdopodobnie podobnego do być, ale jest w pełni PowerShell i stosunkowo łatwe do odczytania

+0

+1, ponieważ będzie działać we wszystkich wersjach powershell 2,3,4, problem z interfejsem [io.path] :: Combine API jest inny dla frameworka .net 3,4 – Ram

7

Jeśli nadal używa .NET 2.0 następnie [IO.Path]::Combine nie będzie miał params string[] przeciążenie, które trzeba dołączyć do więcej niż dwóch części, a zobaczysz błąd nie mogę znaleźć Overl oad dla "Combine" i liczba argumentów: "3".

Nieco mniej elegancki, ale czysty roztwór PowerShell jest ręcznie kruszywa części ścieżki:

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

lub

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

Oto coś, co będzie robić, co tylko chcesz przy użyciu tablicy ciągów dla ChildPath.

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

które wyjścia

C:\Program Files\Microsoft Office 

Jedyne zastrzeżenie znalazłem jest to, że początkowa wartość dla $ path musi mieć wartość (nie może być null lub pusty).

Powiązane problemy