广度优先列表很重要,在这里。此外,限制搜索的深度会很好。
$ 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 one-liner进行此操作。如果有一个javascript-shell,我会想象像
这样的东西bash("find . -type d").sort( function (x) x.findall(/\//g).length; )
答案 0 :(得分:28)
find
命令支持-printf
选项,该选项可识别许多占位符。
一个这样的占位符是%d
,它相对于find
开始的位置呈现给定路径的深度。
因此,您可以使用以下简单的单行:
find -type d -printf '%d\t%P\n' | sort -r -nk1 | cut -f2-
这非常简单,并且不依赖于像perl
这样的重型工具。
工作原理:
答案 1 :(得分:21)
如果您想使用标准工具执行此操作,则以下管道应该可用:
find . -type d | perl -lne 'print tr:/::, " $_"' | sort -n | cut -d' ' -f2
即,
要限制找到的深度,请将-maxdepth参数添加到find命令。
如果您希望以相同顺序列出的目录找到输出它们,请使用“sort -n -s”而不是“sort -n”; “-s”标志稳定排序(即保留相同比较的项目之间的输入顺序)。
答案 2 :(得分: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))
修改强>
os.path
- 模块而不是os.stat
- 函数和stat
- 模块。list.pop
和list.extend
代替del
和+=
运营商。答案 3 :(得分:5)
我的感觉是,这是一个比前面提到的更好的解决方案。它涉及grep等和循环,但我发现它工作得很好,特别适用于你想要行缓冲而不是完全缓冲的情况。
由于以下原因,资源密集程度更高:
这很好,因为:
#!/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
但我更喜欢小脚本而非打字......
答案 4 :(得分:5)
你可以使用find命令, find / path / to / dir -type d 所以下面是当前目录中的目录列表:
find . -type d
答案 5 :(得分:3)
我尝试使用find
找到一种方法,但似乎没有-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
(用深度替换-lt 2
中的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
答案 6 :(得分:2)
没有应得的顺序: find -maxdepth -type d
为了得到应得的排序,你必须自己做这个小shellcript的递归:
#!/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"
然后,您可以使用参数base directory和depth调用此脚本。
答案 7 :(得分:1)
这是一种可能的方法,使用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
答案 8 :(得分:0)
这样的事情:
find . -type d |
perl -lne'push @_, $_;
print join $/,
sort {
length $a <=> length $b ||
$a cmp $b
} @_ if eof'