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?

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.


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

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


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\*\*\*\*"

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 .


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
}

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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.