Если я хочу объединить две строки в путь к файлу, я использую Join-Path
вот так:
$path = Join-Path C: "Program Files"
Write-Host $path
Это печатает "C:\Program Files"
. Если я хочу сделать это более чем для двух строк:
$path = Join-Path C: "Program Files" "Microsoft Office"
Write-Host $path
PowerShell выдает ошибку:
Join-Path: не может быть найден позиционный параметр, который принимает аргумент «Microsoft Office».
В 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
Я пробовал использовать строковый массив:
[string[]] $pieces = "C:", "Program Files", "Microsoft Office"
$path = Join-Path $pieces
Write-Host $path
Но PowerShell предлагает мне ввести дочерний путь (поскольку я не указал -childpath
аргумент), например, «somepath», а затем создает три пути к файлам,
C:\somepath
Program Files\somepath
Microsoft Office\somepath
что тоже неправильно.
источник
Ответы:
Вы можете использовать класс .NET Path :
источник
$PSVersionTable
)? Работает[io.path]::combine([string[]]('c:\','foo','bar'))
?join-path
делает то, что вы ожидаете,join-path "C:\" "\foo"
выводитC:\foo
,Path.Combine
однако игнорирует первый аргумент всякий раз, когда второй аргумент содержит начальный разделитель:[io.path]::combine('c:\', '\foo')
досадно выводит\foo
.Поскольку Join-Path можно передать по конвейеру значение пути, вы можете передать несколько операторов Join-Path вместе:
Это не так лаконично, как вам, вероятно, хотелось бы, но это полностью PowerShell, и его относительно легко читать.
источник
Начиная с PowerShell 6.0, Join-Path имеет новый параметр, называемый,
-AdditionalChildPath
и может объединять несколько частей пути из коробки . Либо предоставив дополнительный параметр, либо просто предоставив список элементов.Пример из документации :
Итак, в PowerShell 6.0 и выше ваш вариант
работает как положено!
источник
Join-Path - это не совсем то, что вы ищете. Он имеет множество применений, но не тот, который вы ищете. Пример из вечеринки с Join-Path :
Вы видите, что он принимает массив строк и объединяет дочернюю строку с каждой, создавая полные пути. В вашем примере
$path = join-path C: "Program Files" "Microsoft Office"
. Вы получаете сообщение об ошибке, поскольку вы передаете три позиционных аргумента иjoin-path
принимаете только два. То, что вы ищете, это-join
, и я мог видеть это недоразумением. Вместо этого рассмотрите это на своем примере:-Join
берет массив элементов и объединяет их\
в одну строку.Незначительная попытка спасения
Да, я согласен, что этот ответ лучше, но мой все еще может работать. Комментарии предполагают, что может быть проблема с косой чертой, поэтому, чтобы сохранить мой подход конкатенации, вы также можете сделать это.
Поэтому, если есть проблемы с лишними косыми чертами, их можно обработать, если они не находятся в начале строки (разрешены пути UNC ).
[io.path]::combine('c:\', 'foo', '\bar\')
не будет работать так, как ожидалось, и я должен это учитывать. Оба требуют правильных строк для ввода, поскольку вы не можете учесть все сценарии. Рассмотрим оба подхода, но да, другой ответ с более высокой оценкой будет более кратким, и я даже не знал, что он существует.Кроме того, я хотел бы указать, что мой ответ объясняет, как то, что делал OP, было неправильным, помимо предложения по решению основной проблемы.
источник
Если вы все еще используете .NET 2.0, у
[IO.Path]::Combine
вас не будетparams string[]
перегрузки, которая вам понадобится для объединения более двух частей, и вы увидите ошибку Не удается найти перегрузку для «Объединить» и количество аргументов: «3».Чуть менее элегантное, но чистое решение PowerShell - это вручную агрегировать части пути:
или
источник
Вот что-то, что будет делать то, что вам нужно при использовании строкового массива для ChildPath.
Какие выходы
Единственное предостережение, которое я обнаружил, заключается в том, что начальное значение для $ path должно иметь значение (не может быть нулевым или пустым).
источник
Вот еще два способа написать чистую функцию PowerShell для объединения произвольного числа компонентов в путь.
Эта первая функция использует один массив для хранения всех компонентов, а затем цикл foreach для их объединения:
Поскольку компоненты пути являются элементами массива и являются частью одного аргумента, они должны быть разделены запятыми. Использование следующее:
Более минималистичный способ написать эту функцию - использовать встроенную
$args
переменную, а затем свернуть цикл foreach в одну строку с помощью метода Майка Фэйра.В отличие от предыдущей версии функции, каждый компонент пути является отдельным аргументом, поэтому для разделения аргументов необходим только пробел:
источник
Следующий подход более лаконичен, чем конвейерные операторы Join-Path:
Затем $ p содержит объединенный путь 'a \ b \ c \ d'.
(Я только что заметил, что это тот же подход, что и у Майка Фэйра, извините.)
источник
Или вы можете написать для него свою собственную функцию (что я и сделал).
Затем вы можете вызвать функцию следующим образом:
Это имеет то преимущество, что имеет то же поведение, что и обычная функция Join-Path, и не зависит от .NET Framework.
источник
Вы можете использовать это так:
источник