Per completare Martin Brandl's helpful answer:
Spe in particolare, il - contro-intuitivo - logic applied by [System.IO.Path]::Combine
è: "Se percorso2 o percorso3 è anche un percorso assoluto, l'operazione di combinazione elimina tutti i percorsi precedentemente combinati e si reimposta su quel percorso assoluto." (questo vale analogamente anche per gli altri metodi).
In altre parole: l'argomento percorso ultimo specificato che inizia con \
(compresi \\
) o <letter>:
provoca tutti i percorsi precedenti essere ignorato (una specifica unità.).
> [IO.Path]::Combine('\foo', '\bar', '\baz')
\baz # !! '\foo' and '\bar' were ignored
Per il comportamento visto - dove una prima \
dovrebbero essere trattati come un componente opzionale di ogni componente del percorso diverso dal primo - garantire che ogni componente, ma il primo non fa inizio con \
- Join-Path
gestisce come ci si aspetterebbe.
Un semplice funzione possono farlo:
# Combines array of path components $a to a single path.
function combine([string[]] $a) {
[IO.Path]::Combine([string[]] (@($a[0]) + $a[1..$($a.count-1)] -replace '^\\', ''))
}
Si noti che la fusione a [string[]]
è fondamentale per far funzionare tutto questo.
chiamata Esempio:
> combine '\foo', '\bar', '\baz'
\foo\bar\baz # as expected
Uso Join-Path
, che supporta solo coppie di componenti come Windows PowerShell v5.1 [1] , alternativa all'utilizzo una pipeline per concatenare più chiamate è quella di nidificare con più chiamate con (...)
:
> Join-Path \foo (Join-Path \bar \baz)
\foo\bar\baz
Nota che, anche se la nidificazione è un po 'imbarazzante, NON è necessario preoccuparsi di componenti subordinate che iniziano con \
.
quanto riguarda la logica del proprio Join-Path
cmdlet di PowerShell:
Mentre è comprensibile aspettarsi il parametro -ChildPath
per supportare un matrice di percorsi (che non), è importante capire che il design Join-Path
's fondamentalmente diversa da quella di [System.IO.Path]::Combine()
, come di Windows PowerShell v5.1 [1] :
Join-Path
utilizza percorsi di ingresso multipli per generare più uscite invece di interpretare i percorsi di ingresso come componenti di un percorso di uscita singolo.
percorsi di ingresso sono coppia (s) di genitore e bambino percorsi, con ogni coppia sempre unito e conseguente nel proprio percorso di output:
> Join-Path \foo \bar \foo\bar
- corto per:
Join-Path -Path \foo -ChildPath \bar
- Nota come PS, a differenza di
[System.IO.Path]::Combine()
, gestisce un \
iniziale opzionale nel bambino percorso come ti aspetteresti.
Mentre il parametro padre-path (-Path
) fa sostegno un matrice di percorsi principali, il parametro bambino-path (-ChildPath
) non non, anche se quando combinato con il -Resolve
parametro e caratteri jolly, può effettivamente risultare in più percorsi figlio.
> Join-Path -Path \foo, \baz -ChildPath \bar \foo\bar \baz\bar
- Si noti come sono stati generati percorsi di uscita, accoppiando ogni percorso genitore con il percorso di un bambino.
differenza [System.IO.Path]::Combine()
, Join-Path
opzionalmente supporta la risoluzione di percorsi jolly con -Resolve
:
> Join-Path -Resolve C:\Win* Sys* C:\Windows\System C:\Windows\System32 C:\Windows\SystemApps C:\Windows\SystemResources C:\Windows\SysWOW64 C:\Windows\system.ini
Infine vale la pena notare che Join-Path
non funziona solo con i percorsi del file system, ma con i percorsi di qualsiasi fornitore di PowerShell [archivio dati gerarchico], applicando la fornitura separatori di percorso appropriati per r.
[1] L'edizione cross-platform PowerShell, PowerShell Nucleo, come di v6.0.0, già fa sostegno un numero arbitrario di componenti figlio, enabling calls such as Join-Path a b c
to yield a\b\c
(Windows) or a/b/c
(Unix), mentre l'edizione nativa per Windows Windows PowerShell a partire dalla versione 5.1 non è ancora disponibile rt it.
Questo nuovo comportamento non è ancora documentato (e non riflette anche la sintassi in base a Join-Path -?
), ma potrebbe essere incluso in Windows PowerShell (e quindi tutte le versioni).
ah grazie ... Ho pensato che questa sorta di intelligenza fosse costruita nella funzione '[System.IO.Path] :: Combine ' – ibiza
Sì, ho pensato anche io, ho appena provato ;-). –
grazie, ho pensato di usare Join-Path ... ma dovrei usare Join-Path per due volte è un po 'triste: p – ibiza