[2..-1]
не работает, поскольку массив индексов , созданный с помощью ..
, оператор диапазона , в данном случае 2, 1, 0, -1
это не то, что вы хотели.
К сожалению, в PowerShell Core 7.0.0-preview.4, единственный способ сослаться на все оставшиеся элементы (или всеОстальные элементы, кроме last (N ), выражаются на основе количества элементов массива , которое требует, чтобы вы захватили массив в переменную first :
Get-ChildItem -File -Recurse -Path "$Env:USERPROFILE\Documents" |
ForEach-Object {
$components = $_.DirectoryName.Split('\')
$components[2..($components.Count-1)] -join '\'
}
Перспективы на будущее: Предоставление удобного синтаксиса индекса, который позволяет ссылаться на все оставшиеся элементы (с [2..]
), а также на все остальные элементы, кроме последнего $n
(счто-то вроде [2..@-$n]
), является предметом этого запроса функции на GitHub .
Примечание: решение на основе конвейера через Select-Object -Skip 2
, как показано в ответе js2010 , удобно, но заметно медленнее , чем решение для нарезки массивов.
Что касается того, что вы пытались :
Предоставление фиксированной верхней границы, такой как 999
, которая известна всегдабыть выше, чем истинное число элементов работает ЕСЛИ И ТОЛЬКО ЕСЛИ (а) эта граница известна и (б) достаточно мала, чтобы не вызывать проблем с памятью / производительностью.
Поэтому, используя что-то вроде 2..([int]::MaxValue-1)
это не вариант.
(На практике в PowerShell Core самый высокий индекс, который вы можете использовать, это [int]::MaxValue - 1048576
([int]::MaxValue - [Math]::Pow(2, 20))
) - но генерирует массив с таким количеством элементов (в качестве индексов) с ..
непомерно медленным и интенсивно использует память).
Если производительность имеет первостепенное значение , используйте решение на основе .Substring()
, в котором просто пропущен путьпрефикс, основанный на пути ввода:
$inputPath = "$Env:USERPROFILE\Documents"
# Determine the length of the prefix
# comprising the input path's first 2 path components.
$prefixLength = ($inputPath -replace '^(.+?\\.+?\\).*', '$1').Length
Get-ChildItem -File -Recurse -Path $inputPath |
ForEach-Object {
$_.DirectoryName.Substring($prefixLength)
}