Limitar la profundidad de recursividad de Get-ChildItem

82

Puedo obtener todos los subelementos de forma recursiva usando este comando:

Get-ChildItem -recurse

Pero, ¿hay alguna forma de limitar la profundidad? ¿Si solo quiero recurrir uno o dos niveles hacia abajo, por ejemplo?

Svish
fuente

Respuestas:

109

Use esto para limitar la profundidad a 2:

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

La forma en que funciona es que devuelve los hijos en cada profundidad 2,1 y 0.


Explicación:

Este comando

Get-ChildItem \*\*\*

devuelve todos los elementos con una profundidad de dos subcarpetas. Agregar \ * agrega una subcarpeta adicional para buscar.

De acuerdo con la pregunta OP, para limitar una búsqueda recursiva usando get-childitem, debe especificar todas las profundidades que se pueden buscar.

CB.
fuente
Tan genial. Supongo que nunca he necesitado hacer esto en PowerShell, pero sé que lo he deseado antes en CMD.EXE.
aphoria
15
Parece que tienes que hacer "-path \ * \ * \ *, \ * \ *, \ *" para llegar a las profundidades intermedias.
Gerard ONeill
Lo intenté, pero parece que sube en lugar de bajar. ¿Cómo puedo usarlo para generar un árbol de carpetas como en superuser.com/questions/258287/… ? Gracias.
Royi
2
Para iniciar la recursividad desde el directorio actual, es necesario agregar un punto al comienzo de cada ruta. Get-ChildItem .\*\*\*,.\*\*,.\*En algún momento, en PowerShell 5.1, Get-ChildItem ahora tiene un -Depthparámetro.
encendido el
65

A partir de powershell 5.0 , ahora puede usar el -Depthparámetro en Get-ChildItem!

Lo combina con -Recursepara limitar la recursividad.

Get-ChildItem -Recurse -Depth 2
De-ver
fuente
4
Parece que el -Recursecambio es opcional / implícito cuando -Depthse especifica.
Charlie Joynt
7
Una cosa que encontré con esto que parece extraño es -Excludecuando se incluye con -Depthniega el -Depthvalor.
Aek
2
@ssaviers El mismo problema ocurre con -Include también.
Eternal21
Por lo que vale, el parámetro -Depth parece ignorarse cuando se combina con comodines. Por ejemplo, gci c:\*.exe -Depth 1devuelve archivos con varios subdirectorios de profundidad.
GuitarPicker
¡Bueno saber! gci c:\ -filter *.exe -depth 1probablemente obtendría lo que quiere @GuitarPicker No tengo una máquina con Windows para probar en este momento, sin embargo
dee-see
9

Prueba esta función:

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

fuente

walid2mi
fuente
1
Realmente funciona. Ejemplo de invocación: Get-ChildItemToDepth -ToDepth 2(trabajando en el directorio actual)
Peter Mortensen
1

Traté de limitar la profundidad de recursividad Get-ChildItem usando Resolve-Path

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

Pero esto funciona bien:

gci "$PATH\*\*\*\*"
scanlegentil
fuente
1

Esta es una función que genera una línea por artículo, con sangría según el nivel de profundidad. Probablemente sea mucho más legible.

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

Se basa en una publicación de blog, Practical PowerShell: poda de árboles de archivos y extensión de cmdlets .

sancho.s ReinstateMonicaCellio
fuente
0

@scanlegentil Me gusta esto.
Una pequeña mejora sería:

$Depth = 2
$Path = "."

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

Como se mencionó, esto solo escanearía la profundidad especificada, por lo que esta modificación es una mejora:

$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
}
kevro
fuente
Esto mostrará todos los nombres de subcarpetas a la profundidad especificada
kevro
1
Esto parece mostrar elementos a una profundidad determinada, no hasta una profundidad determinada.
sancho.s ReinstateMonicaCellio