Jeśli chcę połączyć dwa ciągi w ścieżkę do pliku, używam w Join-Path
ten sposób:
$path = Join-Path C: "Program Files"
Write-Host $path
To drukuje "C:\Program Files"
. Jeśli jednak chcę to zrobić dla więcej niż dwóch ciągów:
$path = Join-Path C: "Program Files" "Microsoft Office"
Write-Host $path
PowerShell zgłasza błąd:
Join-Path: Nie można znaleźć parametru pozycyjnego, który akceptuje argument „Microsoft Office”.
W D: \ users \ ma \ my_script.ps1: 1 char: 18
+ $ path = join-path <<<< C: "Program Files" "Microsoft Office"
+ CategoryInfo: InvalidArgument: (:) [Join-Path] , ParameterBindingException
+ FullyQualifiedErrorId: PositionalParameterNotFound, Microsoft.PowerShell
.Commands.JoinPathCommand
Próbowałem użyć tablicy ciągów:
[string[]] $pieces = "C:", "Program Files", "Microsoft Office"
$path = Join-Path $pieces
Write-Host $path
Ale PowerShell prosi mnie o wpisanie ścieżki potomnej (ponieważ nie podałem -childpath
argumentu), np. „Somepath”, a następnie tworzy trzy ścieżki do plików,
C:\somepath
Program Files\somepath
Microsoft Office\somepath
co też nie jest właściwe.
źródło
$PSVersionTable
)? Działa[io.path]::combine([string[]]('c:\','foo','bar'))
?join-path
robi to, czego się spodziewasz,join-path "C:\" "\foo"
generujeC:\foo
,Path.Combine
jednak ignoruje pierwszy argument, gdy drugi argument zawiera wiodący separator:[io.path]::combine('c:\', '\foo')
denerwujące wyjścia\foo
.Ponieważ Join-Path można przesłać potokiem do wartości ścieżki, można potokować wiele instrukcji Join-Path razem:
Nie jest tak zwięzły, jak byś chciał, ale jest w pełni PowerShell i jest stosunkowo łatwy do odczytania.
źródło
Od PowerShell 6,0 Join-Path ma nowy parametr o nazwie
-AdditionalChildPath
i może łączyć wiele części ścieżki po wyjęciu z pudełka . Albo przez podanie dodatkowego parametru, albo po prostu podając listę elementów.Przykład z dokumentacji :
Więc w PowerShell 6.0 i nowszych wersjach
działa zgodnie z oczekiwaniami!
źródło
Join-Path nie jest dokładnie tym, czego szukasz. Ma wiele zastosowań, ale nie to, czego szukasz. Przykład z Partying with Join-Path :
Widzisz, że akceptuje tablicę ciągów i łączy ciąg potomny z każdym tworzącym pełne ścieżki. W twoim przykładzie
$path = join-path C: "Program Files" "Microsoft Office"
. Otrzymujesz błąd, ponieważ przekazujesz trzy argumenty pozycyjne ijoin-path
akceptujesz tylko dwa. To, czego szukasz, to-join
i widzę, że to nieporozumienie. Zamiast tego rozważ to w swoim przykładzie:-Join
pobiera tablicę elementów i łączy je\
w jeden ciąg.Niewielka próba ratunku
Tak, zgodzę się, że ta odpowiedź jest lepsza, ale moja może 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ć.
Więc jeśli występują problemy z dodatkowymi ukośnikami, można je rozwiązać, o ile nie znajdują się one na początku ciągu (zezwala na ścieżki UNC ).
[io.path]::combine('c:\', 'foo', '\bar\')
nie działałby zgodnie z oczekiwaniami, a mój tłumaczy to. Oba wymagają odpowiednich ciągów danych wejściowych, ponieważ nie można uwzględnić wszystkich scenariuszy. Rozważ oba podejścia, ale tak, druga wysoko oceniana odpowiedź jest bardziej zwięzła i nawet nie wiedziałem, że istnieje.Chciałbym również zwrócić uwagę, że moja odpowiedź wyjaśnia, w jaki sposób to, co robił PO, było złe, oprócz przedstawienia sugestii rozwiązania podstawowego problemu.
źródło
Jeśli nadal używasz .NET 2.0,
[IO.Path]::Combine
nie będzieparams string[]
przeciążenia wymaganego do połączenia więcej niż dwóch części, a zobaczysz błąd Nie można znaleźć przeciążenia dla opcji „Połącz” i liczbę argumentów: „3”.Nieco mniej eleganckie, ale czystym rozwiązaniem PowerShell jest ręczne agregowanie części ścieżki:
lub
źródło
Oto coś, co zrobi to, co chcesz, używając tablicy ciągów dla ChildPath.
Które wyjścia
Jedynym zastrzeżeniem, które znalazłem, jest to, że początkowa wartość ścieżki $ path musi mieć wartość (nie może być pusta ani zerowa).
źródło
Oto dwa inne sposoby na napisanie czystej funkcji PowerShell, aby połączyć dowolną liczbę komponentów w ścieżkę.
Ta pierwsza funkcja używa pojedynczej tablicy do przechowywania wszystkich składników, a następnie pętli foreach do ich połączenia:
Ponieważ składniki ścieżki są elementami tablicy i wszystkie są częścią pojedynczego argumentu, muszą być oddzielone przecinkami. Sposób użycia jest następujący:
Bardziej minimalistycznym sposobem napisania tej funkcji jest użycie
$args
zmiennej wbudowanej , a następnie zwinięcie pętli foreach do jednej linii przy użyciu metody Mike'a Fair'a.W przeciwieństwie do poprzedniej wersji funkcji, każdy składnik ścieżki jest oddzielnym argumentem, więc do oddzielenia argumentów potrzebna jest tylko spacja:
źródło
Poniższe podejście jest bardziej zwięzłe niż potokowanie instrukcji Join-Path:
$ p przechowuje następnie połączoną ścieżkę „a \ b \ c \ d”.
(Właśnie zauważyłem, że jest to dokładnie to samo podejście, co Mike Fair, przepraszam).
źródło
Lub możesz napisać dla niego własną funkcję (co ostatecznie zrobiłem).
Możesz wtedy wywołać funkcję w ten sposób:
Ma to tę zaletę, że zachowuje się dokładnie tak samo, jak normalna funkcja Join-Path i nie zależy od platformy .NET Framework.
źródło
Możesz to wykorzystać w ten sposób:
źródło