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.