如何使用join-path将两个以上的字符串组合到文件路径中?

Mic*_*l A 98 powershell

如果我想将两个字符串组合成文件路径,我使用Join-Path如下:

$path = Join-Path C: "Program Files"
Write-Host $path
Run Code Online (Sandbox Code Playgroud)

那打印"C:\Program Files".如果我想为两个以上的字符串执行此操作:

$path = Join-Path C: "Program Files" "Microsoft Office"
Write-Host $path
Run Code Online (Sandbox Code Playgroud)

Powershell抛出一个错误:

[string[]] $pieces = "C:", "Program Files", "Microsoft Office"
$path = Join-Path $pieces
Write-Host $path
Run Code Online (Sandbox Code Playgroud)

我尝试使用字符串数组:

C:\somepath
Program Files\somepath
Microsoft Office\somepath
Run Code Online (Sandbox Code Playgroud)

但是Powershell提示我输入子路径(因为我没有指定-childpath参数),例如"somepath",然后创建三个文件路径,

$path = Join-Path C: "Program Files"
Write-Host $path
Run Code Online (Sandbox Code Playgroud)

哪个也不对.

Mar*_*man 151

您可以使用.NET Path类:

[IO.Path]::Combine('C:\', 'Foo', 'Bar')
Run Code Online (Sandbox Code Playgroud)

  • 当然是最简洁的形式,并且正确处理路径分片和路径片段上的尾部/前导斜线,这是当前接受的答案(基本字符串连接)不能做到的. (3认同)
  • 为了在我的powershell中执行上面的命令,我得到这个错误 - 找不到"Combine"的重载和参数count:"3".在行:1 char:19 + [io.path] :: combine <<<<('c:\','foo','bar')+ CategoryInfo:NotSpecified:(:) [],MethodException + FullyQualifiedErrorId: MethodCountCouldNotFindBest (3认同)
  • @DavidKeaveny“正确处理路径分隔符以及路径片段上的尾随/前导斜杠” –并非如此。`join-path`符合您的期望,`join-path“ C:\”“ \ foo”`输出`C:\ foo`,`Path.Combine`会在第二个参数包含前导分隔符时忽略第一个参数:`[io.path] :: combine('c:\','\ foo')`令人讨厌地输出`\ foo`。 (2认同)

Dav*_*eny 89

由于Join-Path可以通过管道传递其路径值,因此您可以将多个Join-Path语句组合在一起:

Join-Path "C:" -ChildPath "Windows" | Join-Path -ChildPath "system32" | Join-Path -ChildPath "drivers"
Run Code Online (Sandbox Code Playgroud)

它并不像你希望的那样简洁,但它完全是PowerShell并且相对容易阅读

  • +1因为它将适用于所有powershell 2,3,4,[io.path] :: Combine API的问题与.net框架3,4不同 (2认同)

Mat*_*att 15

Join-Path并不完全符合您的要求.它有多种用途,但不是您正在寻找的用途.使用Join-Path进行Partying的示例

Join-Path C:\hello,d:\goodbye,e:\hola,f:\adios world
C:\hello\world
d:\goodbye\world
e:\hola\world
f:\adios\world
Run Code Online (Sandbox Code Playgroud)

您会看到它接受一个字符串数组,并将子字符串连接到每个创建完整路径的字符串.在你的例子中$path = join-path C: "Program Files" "Microsoft Office".您收到错误,因为您传递3个位置参数并且join-path只接受2.您正在寻找的是一个-join,我可以看到这是一个误解.请考虑使用您的示例:

"C:","Program Files","Microsoft Office" -join "\"
Run Code Online (Sandbox Code Playgroud)

-Join获取项目数组并将它们连接\成一个字符串.

C:\Program Files\Microsoft Office
Run Code Online (Sandbox Code Playgroud)

轻微的打捞尝试

是的,我会同意这个答案更好但我的仍然有效.评论表明可能存在斜杠问题,因此为了保持我的连接方法,您也可以这样做.

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

因此,如果存在额外斜杠的问题,只要它们不在字符串的开头(允许UNC路径),就可以处理它.[io.path]::combine('c:\', 'foo', '\bar\')不会按预期工作,我的将会解释这一点.两者都需要适当的输入字符串,因为您无法考虑所有情况.考虑两种方法,但是其他更高评价的答案更简洁,我甚至不知道它存在.

另外,我想指出,我的回答解释了在提出解决核心问题的建议之后OP如何做错了.

  • 这是错误的,因为即使多个连续的\ in路径将起作用,它也很丑陋并且可能导致问题. (2认同)
  • 我最近一直在处理大量低质量代码,人们通过String.Equals比较路径,并使用String.Split('\\')解析路径,而不删除空字符串.我无法想到任何更危险的后果,大多数情况下我只是偏执狂.感谢您的编辑. (2认同)
  • 明确包含路径分隔符可能会导致跨平台可移植性问题。虽然PowerShell当前仅在Windows上运行,但在不久的将来有可能会改变,并且最好早日养成良好的习惯。更不用说这些习惯可以转移到其他语言。 (2认同)

Mar*_*orf 13

从PowerShell 6.0开始,Join-Path具有一个名为的新参数-AdditionalChildPath,可以直接组合路径的多个部分。通过提供额外的参数或仅提供元素列表即可。

文档中的示例:

Join-Path a b c d e f g
a\b\c\d\e\f\g
Run Code Online (Sandbox Code Playgroud)

因此在PowerShell 6.0及更高版本中

$path = Join-Path C: "Program Files" "Microsoft Office"
Run Code Online (Sandbox Code Playgroud)

正常工作!


Kon*_*rin 7

如果你还在使用的.Net 2.0,然后[IO.Path]::Combine将没有params string[]超载,你需要连接两个以上的部分,你会看到错误无法找到"组合"过载和参数计数:"3".

稍微不那么优雅但纯粹的Powershell解决方案是手动聚合路径部分:

Join-Path C: (Join-Path  "Program Files" "Microsoft Office")
Run Code Online (Sandbox Code Playgroud)

要么

Join-Path  (Join-Path  C: "Program Files") "Microsoft Office"
Run Code Online (Sandbox Code Playgroud)


Mik*_*air 5

在为 ChildPath 使用字符串数组时,这里有一些可以做你想做的事情。

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

哪些输出

C:\Program Files\Microsoft Office
Run Code Online (Sandbox Code Playgroud)

我发现的唯一警告是 $path 的初始值必须有一个值(不能为 null 或为空)。


Jon*_*Jon 5

这里有另外两种编写纯 PowerShell 函数以将任意数量的组件连接到路径中的方法。

第一个函数使用单个数组来存储所有组件,然后使用 foreach 循环来组合它们:

function Join-Paths {
    Param(
        [Parameter(mandatory)]
        [String[]]
        $Paths
    )
    $output = $Paths[0]
    foreach($path in $Paths[1..$Paths.Count]) {
        $output = Join-Path $output -ChildPath $path
    }
    $output
}
Run Code Online (Sandbox Code Playgroud)

因为路径组件是数组中的元素并且是单个参数的所有部分,所以它们必须用逗号分隔。用法如下:

PS C:\> Join-Paths 'C:', 'Program Files', 'Microsoft Office'
C:\Program Files\Microsoft Office


编写此函数的一种更简约的方法是使用内置$args变量,然后使用 Mike Fair 的方法将 foreach 循环折叠为一行。

function Join-Paths2 {
    $path = $args[0]
    $args[1..$args.Count] | %{ $path = Join-Path $path $_ }
    $path
}
Run Code Online (Sandbox Code Playgroud)

与之前版本的函数不同,每个路径组件都是一个单独的参数,因此只需要一个空格来分隔参数:

PS C:\> Join-Paths2 'C:' '程序文件' 'Microsoft Office'
C:\Program Files\Microsoft Office