在Powershell中列出给定深度以下的文件夹

时间:2019-03-06 17:58:57

标签: powershell recursion depth directory-structure

我有一个包含很多文件夹的目录。我想列出深度超过2级的所有文件夹(路径)。因此,在以下情况下,文件夹1和2。

Directory/folder1
Directory/folder1/test1/test/testsub
Directory/folder1/test2
Directory/folder1/test3
Directory/folder2/blablabla/bla/1
Directory/folder3/test
Directory/folder4/test
Directory/folder5/test

我正在尝试以下操作:

$Depth = 3
$Path = "."

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

2 个答案:

答案 0 :(得分:1)

下面直接基于您自己构建的解决方案,假定您的意图是查找那些子树超过给定深度的子目录

如果您想查找位于给定深度或更深的所有目录路径,请参见底部。
您的方法无法实现这一点,因为它只能在给定深度下找到目录,而不能在下面找到。


您自己的基于通配符的聪明方法原则上应该可以使用,但是:

  • (a)可以大大简化。

  • (b)需要做更多工作才能将输出限制到子树太深的那些子文件夹的不同列表。

(a)简化方法:

$Depth = 3
$Path = '.'

$Levels = '/*' * $Depth
Get-ChildItem -Directory $Path/$Levels
  • 与您自己的方法一样,'/*' * $Depth动态创建一个多目录级通配符表达式(例如,/*/*$Depth的{​​{1}})可以附加到输入2上,以仅匹配该级别的路径。

  • $Path开关(PSv3 +)限制仅与目录匹配。

(b)将输出限制为具有太深子树的顶级文件夹的不同集合:

-Directory

注意:通过$Depth = 3 $Path = '.' $Levels = '/*' * $Depth Get-ChildItem -Directory $Path/$Levels | ForEach-Object { ($_.FullName -split '[\\/]')[-$Depth] } | Select-Object -Unique (即,通过[/\\]/进行拆分)也使解决方案也可以在类似Unix的平台上运行(PowerShell Core < / em>);在Windows上,\(通过转义的-split '\\')就足够了。

使用示例文件夹层次结构,以上内容将产生:

\
  • 如果要使用完整路径,请附加
    folder1 folder2

  • 如果要使用目录信息对象| Convert-Path -LiteralPath { "$Path/$_" }),请附加
    [System.IO.DirectoryInfo]


可选阅读:使文件夹达到,达到或超过特定深度:

注意:

  • 即使目标文件夹(目录)下的解决方案也可以通过简单地省略| Get-Item -LiteralPath { "$Path/$_" }来包含文件,或者仅将目标文件将-Directory替换为-Directory

  • 为简单起见,这些命令隐式地针对当前目录。


“仅给出深度” 逻辑:

这与上面的解决方案中使用的逻辑相同;以下代码列出了深度仅为2的文件夹,即子级(即子目录的子目录)-请注意,与-File不同,深度计数从{{1}开始},即Get-ChildItem -Depth指向子目录:

1
  • 要输出完整路径,请将1命令放在$depth = 2 # grandchild directories only Get-ChildItem -Directory -Path ('*/' * $depth) 中,或将其通过管道传递到Get-ChildItem

  • 要输出相对路径(例如(...).FullName),还需要进行其他工作,因为添加Select-Object -ExpandProperty FullName不会 在这种情况下是预期的(它将仅输出目录名称):

folder1/test1/test/testsub

深入-深度逻辑:

PSv5 + -Name 参数限制$depth = 2 # grandchild directories # Calculate the length of the path prefix for determining relative paths. # (Using the current dir ($PWD) as the reference path here.) $PrefixLen = (Convert-Path -LiteralPath $PWD).Length + 1 $Levels = '/*' * $Depth Get-ChildItem -Directory -Path ('*/' * $depth) | ForEach-Object { $_.FullName.Substring($PrefixLen) } 的递归深度,即,它只能找到指定深度的项,但请注意深度-Depth ,而不是Get-ChildItem代表直属孩子
请注意,使用0 暗示 1,尽管您也可以指定后者。

例如,要枚举当前目录中的子文件夹和孙子文件夹(2个级别),请使用:

-Depth
  • 要输出完整路径,请将-Recurse命令放在$depth = 2 # child and grandchild directories Get-ChildItem -Directory -Depth ($depth - 1) 中,或将其通过管道传递到Get-ChildItem

  • 要输出相对路径,只需将(...).FullName开关添加到Select-Object -ExpandProperty FullName调用中即可。

给出的深度或深度逻辑:

将结果限制为大于或等于给定深度的项目需要自定义解决方案:

-Name

如果您的输入路径不是(隐含的)当前目录,请将该路径替换为Get-ChildItem

  • 要输出完整路径,请将$depth = 2 # grandchild directories and below Get-ChildItem -Directory -Name -Recurse | Where-Object { ($_ -split '[/\\]').Count -ge 2 } | Get-Item -LiteralPath { "$PWD/$_" } 替换为$PWD

  • 要输出相对路径,只需省略Get-Item调用。

答案 1 :(得分:-1)

请尝试这个

$Folders = Get-ChildItem 'C:\Program Files' -Directory -Recurse -Depth 1 | 
     Select-Object -ExpandProperty fullname | 
     Sort-Object
$Folders