限制 Get-ChildItem 递归深度

我可以使用以下命令递归地获取所有子项:

Get-ChildItem -recurse

但是有没有办法限制深度呢?如果我只想递归一个或两个级别下来,例如?

126183 次浏览

Use this to limit the depth to 2:

Get-ChildItem \*\*\*,\*\*,\*

The way it works is that it returns the children at each depth 2,1 and 0.


Explanation:

This command

Get-ChildItem \*\*\*

returns all items with a depth of two subfolders. Adding \* adds an additional subfolder to search in.

In line with the OP question, to limit a recursive search using get-childitem you are required to specify all the depths that can be searched.

Try this function:

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)")
}
}
}
}

source

I tried to limit Get-ChildItem recursion depth using Resolve-Path

$PATH = "."
$folder = get-item $PATH
$FolderFullName = $Folder.FullName
$PATHs = Resolve-Path $FolderFullName\*\*\*\
$Folders = $PATHs | get-item | where {$_.PsIsContainer}

But this works fine :

gci "$PATH\*\*\*\*"

@scanlegentil I like this.
A little improvement would be:

$Depth = 2
$Path = "."


$Levels = "\*" * $Depth
$Folder = Get-Item $Path
$FolderFullName = $Folder.FullName
Resolve-Path $FolderFullName$Levels | Get-Item | ? {$_.PsIsContainer} | Write-Host

As mentioned, this would only scan the specified depth, so this modification is an improvement:

$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
}

This is a function that outputs one line per item, with indentation according to depth level. It is probably much more readable.

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
}
}
}
}

It is based on a blog post, Practical PowerShell: Pruning File Trees and Extending Cmdlets.

As of powershell 5.0, you can now use the -Depth parameter in Get-ChildItem!

You combine it with -Recurse to limit the recursion.

Get-ChildItem -Recurse -Depth 2

$path = C:
$depth = 0 #, 0 is base, 1 folder deeper, 2 folders deeper

Get-ChildItem -Path $path -Depth $depth | Where-Object {$_.Extension -eq ".extension"}