如何递归列出某个位置的所有目录,广度优先?

And*_*rov 29 linux bash shell ksh

广度优先列表在这里很重要.此外,限制搜索的深度将是很好的.

$ find . -type d
/foo
/foo/subfoo
/foo/subfoo/subsub
/foo/subfoo/subsub/subsubsub
/bar
/bar/subbar

$ find . -type d -depth
/foo/subfoo/subsub/subsubsub
/foo/subfoo/subsub
/foo/subfoo
/foo
/bar/subbar
/bar

$ < what goes here? >
/foo
/bar
/foo/subfoo
/bar/subbar
/foo/subfoo/subsub
/foo/subfoo/subsub/subsubsub
Run Code Online (Sandbox Code Playgroud)

如果可能的话,我想使用bash one-liner进行此操作.如果有一个javascript-shell,我会想象类似的东西

bash("find . -type d").sort( function (x) x.findall(/\//g).length; )
Run Code Online (Sandbox Code Playgroud)

Pet*_*lka 30

find命令支持-printf识别许多占位符的选项.

一个这样的占位符是%d相对于find开始的位置呈现给定路径的深度.

因此,您可以使用以下简单的单行:

find -type d -printf '%d\t%P\n' | sort -r -nk1 | cut -f2-
Run Code Online (Sandbox Code Playgroud)

它非常简单,并且不依赖于重型工具perl.

这个怎么运作:

  • 它在内部生成文件列表,每个文件都呈现为两个字段的行
  • 第一个字段包含深度,用于(反向)数字排序,然后切除
  • 结果是简单的文件列表,每行一个文件,以最深的顺序排列


Emi*_*Sit 23

如果您想使用标准工具执行此操作,则以下管道应该可以正常工作:

find . -type d | perl -lne 'print tr:/::, " $_"' | sort -n | cut -d' ' -f2
Run Code Online (Sandbox Code Playgroud)

那是,

  1. 在这里找到并打印所有目录的第一顺序
  2. 计算每个目录中的斜杠数,并将其添加到路径中
  3. 按深度排序(即斜线数)
  4. 只提取路径.

要限制找到的深度,请将-maxdepth参数添加到find命令.

如果您希望以相同顺序列出的目录找到输出它们,请使用"sort -n -s"而不是"sort -n"; "-s"标志稳定排序(即,保持相等比较的项目之间的输入顺序).


小智 7

您可以使用find命令,find/path/to/dir -type d以下示例当​​前目录中的目录列表:

find . -type d
Run Code Online (Sandbox Code Playgroud)


Ada*_*eld 5

我不认为你可以使用内置实用程序来实现它,因为在遍历目录层次结构时,你几乎总是需要深度优先搜索,无论是自上而下还是自下而上.这是一个Python脚本,它将为您提供广度优先搜索:

import os, sys

rootdir = sys.argv[1]
queue = [rootdir]

while queue:
    file = queue.pop(0)
    print(file)
    if os.path.isdir(file):
        queue.extend(os.path.join(file,x) for x in os.listdir(file))
Run Code Online (Sandbox Code Playgroud)

编辑:

  1. 使用os.path-module代替os.stat-function和stat-module.
  2. 使用list.poplist.extend代替del+=运算符.


Cla*_*nny 5

我的感觉是,这是一个比前面提到的更好的解决方案.它涉及grep和这样的循环,但我发现它非常有效,特别是对于你想要的东西是行缓冲的而不是完整的find缓冲的情况.

由于以下原因,资源更加密集:

  • 很多分叉
  • 很多发现
  • 在当前深度之前的每个目录被find命中多次,因为文件结构的总深度(如果你有几乎任何数量的ram,这应该不是问题...)

这很好,因为:

  • 它使用bash和基本的gnu工具
  • 它可以随时打破(就像你看到你想要飞过的那样)
  • 它适用于每行而不是每个查找,因此后续命令不必等待查找和排序
  • 它基于实际的文件系统分离工作,所以如果你有一个带有斜杠的目录,它将不会被列入比它更深的列表; 如果您配置了不同的路径分隔符,您仍然可以.
#!/bin/bash 
depth=0

while find -mindepth $depth -maxdepth $depth | grep '.'
do
    depth=$((depth + 1))
done

你也可以轻松地将它放到一行(?)上:

depth=0; while find -mindepth $depth -maxdepth $depth | grep --color=never '.'; do depth=$((depth + 1)); done
Run Code Online (Sandbox Code Playgroud)

但我更喜欢小脚本而非打字......