广度优先列表在这里很重要。 此外,限制search的深度将是很好的。
$ 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
如果可能的话,我想用bash单线程来做这个。 如果有一个JavaScript的shell,我会想像的东西
bash("find . -type d").sort( function (x) x.findall(/\//g).length; )
find
命令支持-printf
选项,它可以识别很多占位符。
一个这样的占位符是%d
,它呈现给定路径的深度,相对于开始的位置。
因此,您可以使用以下简单的一行:
find -type d -printf '%d\t%P\n' | sort -r -nk1 | cut -f2-
这是相当简单的,并不依赖像perl
这样的重工具。
怎么运行的:
如果你想使用标准工具来做,下面的管道应该工作:
find . -type d | perl -lne 'print tr:/::, " $_"' | sort -n | cut -d' ' -f2
那是,
要限制找到的深度,请将-maxdepth参数添加到find命令。
如果您想要以相同顺序列出的目录中查找输出,请使用“sort -n -s”而不是“sort -n”。 “-s”标志使排序稳定(即,在相同比较的项目之间保留输入顺序)。
我的感觉是,这是比以前提到的更好的解决方案。 它涉及grep和这样一个循环,但我觉得它工作得很好,特别是对于你想要的东西行缓冲,而不是完整的发现缓冲。
这是更加资源密集的,因为:
这是很好的,因为:
#!/斌/庆典 深度= 0 同时找到-mindepth $ depth -maxdepth $ depth | grep'。 做 depth = $((depth + 1)) DONE
你也可以很容易地把它合理地放在一行上:
depth=0; while find -mindepth $depth -maxdepth $depth | grep --color=never '.'; do depth=$((depth + 1)); done
但是我更喜欢小键盘输入
我不认为你可以使用内置实用程序来完成,因为在遍历目录层次结构时,你几乎总是需要自上而下或自下而上的深度优先搜索。 这是一个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))
编辑:
os.path
-module代替os.stat
和stat
-module。 list.pop
和list.extend
代替del
和+=
运算符。 我试图找到一种方法来做到这一点,但它似乎没有任何像-breadth
选项。 为它写一个补丁,尝试下面的shell咒语(bash):
LIST="$(find . -mindepth 1 -maxdepth 1 -type d)"; while test -n "$LIST"; do for F in $LIST; do echo $F; test -d "$F" && NLIST="$NLIST $(find $F -maxdepth 1 -mindepth 1 -type d)"; done; LIST=$NLIST; NLIST=""; done
我偶然发现了这种情况,所以我不知道它是否能够正常工作(我只是在你所问的特定目录结构上进行测试)
如果你想限制深度,在外部循环中加一个计数器变量,就像这样(我也在给这个加注释):
# initialize the list of subdirectories being processed LIST="$(find . -mindepth 1 -maxdepth 1 -type d)"; # initialize the depth counter to 0 let i=0; # as long as there are more subdirectories to process and we haven't hit the max depth while test "$i" -lt 2 -a -n "$LIST"; do # increment the depth counter let i++; # for each subdirectory in the current list for F in $LIST; do # print it echo $F; # double-check that it is indeed a directory, and if so # append its contents to the list for the next level test -d "$F" && NLIST="$NLIST $(find $F -maxdepth 1 -mindepth 1 -type d)"; done; # set the current list equal to the next level's list LIST=$NLIST; # clear the next level's list NLIST=""; done
(用深度替换2 in -lt 2
)
基本上这实现了标准的广度优先搜索算法,使用$LIST
和$NLIST
作为目录名称的队列。 这是后一种方法,作为一个简单的复制和粘贴的方式:
LIST="$(find . -mindepth 1 -maxdepth 1 -type d)"; let i=0; while test "$i" -lt 2 -a -n "$LIST"; do let i++; for F in $LIST; do echo $F; test -d "$F" && NLIST="$NLIST $(find $F -maxdepth 1 -mindepth 1 -type d)"; done; LIST=$NLIST; NLIST=""; done
没有理所当然的排序:find -maxdepth -type d
为了得到应有的顺序,你必须自己做这个递归:
#!/bin/bash r () { let level=$3+1 if [ $level -gt $4 ]; then return 0; fi cd "$1" for d in *; do if [ -d "$d" ]; then echo $2/$d fi; done for d in *; do if [ -d "$d" ]; then (r "$d" "$2/$d" $level $4) fi; done } r "$1" "$1" 0 "$2"
然后你可以调用这个脚本参数的基础目录和深度。
你可以使用find命令,找到/ path / to / dir -type d那么下面的例子就是当前目录中的目录列表:
find . -type d
这是一个可能的方式,使用find。 我还没有彻底测试过,所以用户要小心…
depth=0 output=$(find . -mindepth $depth -maxdepth $depth -type d | sort); until [[ ${#output} -eq 0 ]]; do echo "$output" let depth=$depth+1 output=$(find . -mindepth $depth -maxdepth $depth -type d | sort) done
像这样的东西:
find . -type d | perl -lne'push @_, $_; print join $/, sort { length $a <=> length $b || $a cmp $b } @_ if eof'