¿Cómo obtengo solo directorios con Get-ChildItem?


242

Estoy usando PowerShell 2.0 y quiero canalizar todos los subdirectorios de una ruta determinada. El siguiente comando genera todos los archivos y directorios, pero no puedo entender cómo filtrar los archivos.

Get-ChildItem c:\mypath -Recurse

He intentado usar $_.Attributespara obtener los atributos, pero no sé cómo construir una instancia literal System.IO.FileAttributespara compararlo. En cmd.exeeso estaría

dir /b /ad /s

Respuestas:


292

Para versiones de PowerShell inferiores a 3.0:

El FileInfoobjeto devuelto por Get-ChildItemtiene una propiedad "base", PSIsContainer. Desea seleccionar solo esos elementos.

Get-ChildItem -Recurse | ?{ $_.PSIsContainer }

Si desea los nombres de cadena sin formato de los directorios, puede hacer

Get-ChildItem -Recurse | ?{ $_.PSIsContainer } | Select-Object FullName

Para PowerShell 3.0 y superior:

dir -Directory

20
Ojalá tuviera un alias de "IsFolder".
xcud

55
xcud: no todas las jerarquías representadas por un PSDrive están basadas en carpetas.
Joey

10
La brecha semántica entre "contenedor" y "carpeta" no puede atravesar un camión.
xcud

55
@xcud: Vea la respuesta de iraSenthil. -Directory y -File también funciona en Get-ChildItem. No es necesario usar el atributo PSIsContainer directamente.
Wouter

(Get-ChildItem |? {$ _. PSIsContainer} | Seleccionar nombre) .Nombre
Jose Ortega

195

En PowerShell 3.0, es más simple:

Get-ChildItem -Directory #List only directories
Get-ChildItem -File #List only files

33
dir es un alias para Get-ChildItem
Chip McCormick

1
@crashmstr ¿Estás seguro? Revisé mi PS4.0. Para mí, dirtenía un alias Get-ChildItem, y las opciones -Directoryy -Filefuncionaron como se describe. Solía comandos echo $PSVersionTable, help dir, dir -Directoryy dir -Filepara llegar a este comentario.
Peter Hull

3
Esta debería ser la respuesta
Chris S

2
lsy dirson alias de Get-ChildItemelegir tu veneno
Kolob Canyon

53

Utilizar

Get-ChildItem -dir #lists only directories
Get-ChildItem -file #lists only files

Si prefiere alias, use

ls -dir #lists only directories
ls -file #lists only files

o

dir -dir #lists only directories
dir -file #lists only files

Para recurrir subdirectorios también, agregue la -ropción.

ls -dir -r #lists only directories recursively
ls -file -r #lists only files recursively 

Probado en PowerShell 4.0, PowerShell 5.0 (Windows 10), PowerShell Core 6.0 (Windows 10, Mac y Linux) y PowerShell 7.0 (Windows 10, Mac y Linux).

Nota : En PowerShell Core, los enlaces simbólicos no se siguen cuando especifica el -rconmutador. Para seguir enlaces simbólicos, especifique el -FollowSymlinkinterruptor con -r.

Nota 2 : PowerShell ahora es multiplataforma, desde la versión 6.0. La versión multiplataforma se llamaba originalmente PowerShell Core, pero la palabra "Core" se ha eliminado desde PowerShell 7.0+.

Documentación de Get-ChildItem: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/get-childitem


2
Esto no funcionará en Powershell 2.0, que era la necesidad específica del OP. el - [/ Dir / Directory] no son parámetros válidos en Powershell 2.0
Ben Personick

21

Un enfoque más limpio:

Get-ChildItem "<name_of_directory>" | where {$_.Attributes -match'Directory'}

Me pregunto si PowerShell 3.0 tiene un conmutador que solo devuelve directorios; Parece una cosa lógica agregar.


1
FYI powershell 3.0 agrega las banderas -Directoryy-File
WickyNilliams


6

Desde PowerShell v2 y posteriores (k representa la carpeta en la que está comenzando su búsqueda):

Get-ChildItem $Path -attributes D -Recurse

Si solo desea nombres de carpetas, y nada más, use esto:

Get-ChildItem $Path -Name -attributes D -Recurse

Si está buscando una carpeta específica, puede usar lo siguiente. En este caso, estoy buscando una carpeta llamada myFolder:

Get-ChildItem $Path -attributes D -Recurse -include "myFolder"

¿Y con PS 3.0 o 4.0?
Kiquenet

55
El parámetro Atributos no parece estar en PS2, da un error "No se puede encontrar un parámetro que coincida con el nombre del parámetro 'Atributos'". Funciona bien en PS3.
WileCau

5

Se requiere menos texto con este enfoque:

ls -r | ? {$_.mode -match "d"}

Este es el que usaría.
David Betz

2
Aún más corto: ls -r | ? {$ _. mode -match "d"}
jyggorath

Esto no encuentra carpetas comprimidas
Charles Lambert

77
Porque una carpeta comprimida es un archivo zip
user1594322

No siempre es útil repetir todo. Podría tener un árbol extremadamente profundo y tupido donde solo le interesen los directorios exactamente dos niveles más abajo; buscar treinta niveles más abajo es una pérdida de tiempo.
Ross Presser

4

Utilizar:

dir -Directory -Recurse | Select FullName

Esto le dará una salida de la estructura raíz con el nombre de la carpeta solo para directorios.


3

Utilizar:

Get-ChildItem \\myserver\myshare\myshare\ -Directory | Select-Object -Property name |  convertto-csv -NoTypeInformation  | Out-File c:\temp\mydirectorylist.csv

Que hace lo siguiente

  • Obtenga una lista de directorios en la ubicación de destino: Get-ChildItem \\myserver\myshare\myshare\ -Directory
  • Extraiga solo el nombre de los directorios: Select-Object -Property name
  • Convierta la salida al formato CSV: convertto-csv -NoTypeInformation
  • Guarde el resultado en un archivo: Out-File c:\temp\mydirectorylist.csv

2
Sería genial si puedes explicar cada paso para que más personas puedan ver lo que está sucediendo.
jazzurro

Esto no funcionará en Powershell 2.0, que era la necesidad específica del OP. el - [/ Dir / Directory] no son parámetros válidos en Powershell 2.0
Ben Personick

2

Se podría lograr un enfoque un poco más legible y simple con el siguiente script:

$Directory = "./"
Get-ChildItem $Directory -Recurse | % {
    if ($_.Attributes -eq "Directory") {
        Write-Host $_.FullName
    }
}

¡Espero que esto ayude!


2

Querrá usar Get-ChildItem para obtener recursivamente todas las carpetas y archivos primero. Y luego canalice esa salida en una cláusula Where-Object que solo toma los archivos.

# one of several ways to identify a file is using GetType() which
# will return "FileInfo" or "DirectoryInfo"
$files = Get-ChildItem E:\ -Recurse | Where-Object {$_.GetType().Name -eq "FileInfo"} ;

foreach ($file in $files) {
  echo $file.FullName ;
}

1

La respuesta aceptada menciona

Get-ChildItem -Recurse | ?{ $_.PSIsContainer } | Select-Object FullName

para obtener una "cadena cruda". Pero, de hecho, los objetos de tipo Selected.System.IO.DirectoryInfoserán devueltos. Para cadenas sin formato se puede usar lo siguiente:

Get-ChildItem -Recurse | ?{ $_.PSIsContainer } | % { $_.FullName }

La diferencia es importante si el valor se concatena en una cadena:

  • con Select-Objectsorprendentefoo\@{FullName=bar}
  • con el ForEachoperador el esperado:foo\bar

1
Select-Object en realidad devolverá objetos del tipo PSCustomObject. Aunque se puede usar% (que es ForEach-Object) para obtener las cadenas primas como lo hizo, también se puede utilizarSelect-Object -ExpandProperty FullName
JamesQMurphy


0

Usa este:

Get-ChildItem -Path \\server\share\folder\ -Recurse -Force | where {$_.Attributes -like '*Directory*'} | Export-Csv -Path C:\Temp\Export.csv -Encoding "Unicode" -Delimiter ";"

0

Para responder la pregunta original específicamente (usando IO.FileAttributes):

Get-ChildItem c:\mypath -Recurse | Where-Object {$_.Attributes -and [IO.FileAttributes]::Directory}

Sin embargo, prefiero la solución de Marek ( Where-Object { $_ -is [System.IO.DirectoryInfo] }).

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.