Я могу рекурсивно получить все подпункты с помощью этой команды:
Get-ChildItem -recurse
Но есть ли способ ограничить глубину? Если я хочу, например, вернуться на один или два уровня вниз?
Ответы:
Используйте это, чтобы ограничить глубину до 2:
Get-ChildItem \*\*\*,\*\*,\*
Это работает так: он возвращает потомков на каждой глубине 2,1 и 0.
Пояснение:
Эта команда
Get-ChildItem \*\*\*
возвращает все элементы с глубиной в две подпапки. Добавление \ * добавляет дополнительную подпапку для поиска.
В соответствии с вопросом OP, чтобы ограничить рекурсивный поиск с использованием get-childitem, вам необходимо указать все глубины, на которых можно выполнять поиск.
Get-ChildItem .\*\*\*,.\*\*,.\*
В какой-то момент в PowerShell 5.1 Get-ChildItem теперь имеет -Depth
параметр.
Начиная с powershell 5.0 , теперь вы можете использовать -Depth
параметр в Get-ChildItem
!
Вы комбинируете его с, -Recurse
чтобы ограничить рекурсию.
Get-ChildItem -Recurse -Depth 2
-Recurse
переключатель является необязательным / подразумевается, когда -Depth
он указан.
-Exclude
что включение с -Depth
отрицает -Depth
значение.
gci c:\*.exe -Depth 1
возвращает файлы в несколько подкаталогов в глубину.
gci c:\ -filter *.exe -depth 1
вероятно, вы получите то, что вы хотите @GuitarPicker У меня сейчас нет Windows-машины для тестирования
Попробуйте эту функцию:
Function Get-ChildItemToDepth {
Param(
[String]$Path = $PWD,
[String]$Filter = "*",
[Byte]$ToDepth = 255,
[Byte]$CurrentDepth = 0,
[Switch]$DebugMode
)
$CurrentDepth++
If ($DebugMode) {
$DebugPreference = "Continue"
}
Get-ChildItem $Path | %{
$_ | ?{ $_.Name -Like $Filter }
If ($_.PsIsContainer) {
If ($CurrentDepth -le $ToDepth) {
# Callback to this function
Get-ChildItemToDepth -Path $_.FullName -Filter $Filter `
-ToDepth $ToDepth -CurrentDepth $CurrentDepth
}
Else {
Write-Debug $("Skipping GCI for Folder: $($_.FullName) " + `
"(Why: Current depth $CurrentDepth vs limit depth $ToDepth)")
}
}
}
}
Get-ChildItemToDepth -ToDepth 2
(работает в текущем каталоге)
Я пытался ограничить глубину рекурсии Get-ChildItem с помощью Resolve-Path
$PATH = "."
$folder = get-item $PATH
$FolderFullName = $Folder.FullName
$PATHs = Resolve-Path $FolderFullName\*\*\*\
$Folders = $PATHs | get-item | where {$_.PsIsContainer}
Но это нормально работает:
gci "$PATH\*\*\*\*"
Это функция, которая выводит по одной строке для каждого элемента с отступом в соответствии с уровнем глубины. Вероятно, это гораздо более читабельно.
function GetDirs($path = $pwd, [Byte]$ToDepth = 255, [Byte]$CurrentDepth = 0)
{
$CurrentDepth++
If ($CurrentDepth -le $ToDepth) {
foreach ($item in Get-ChildItem $path)
{
if (Test-Path $item.FullName -PathType Container)
{
"." * $CurrentDepth + $item.FullName
GetDirs $item.FullName -ToDepth $ToDepth -CurrentDepth $CurrentDepth
}
}
}
}
Он основан на сообщении в блоге « Практическая оболочка PowerShell: сокращение файловых деревьев и расширение командлетов» .
@scanlegentil Мне это нравится.
Небольшое улучшение было бы:
$Depth = 2
$Path = "."
$Levels = "\*" * $Depth
$Folder = Get-Item $Path
$FolderFullName = $Folder.FullName
Resolve-Path $FolderFullName$Levels | Get-Item | ? {$_.PsIsContainer} | Write-Host
Как уже упоминалось, это будет сканировать только указанную глубину, поэтому эта модификация является улучшением:
$StartLevel = 1 # 0 = include base folder, 1 = sub-folders only, 2 = start at 2nd level
$Depth = 2 # How many levels deep to scan
$Path = "." # starting path
For ($i=$StartLevel; $i -le $Depth; $i++) {
$Levels = "\*" * $i
(Resolve-Path $Path$Levels).ProviderPath | Get-Item | Where PsIsContainer |
Select FullName
}