Unix-仅列出包含子目录的目录

问题描述 投票:2回答:3

如何在Unix Shell中打印包含其他目录的树中目录的数量?

我还没有找到像findls这样的命令的解决方案。

linux shell unix command
3个回答
0
投票

如果生成特定目录下所有目录的列表,然后从名称中删除最后一个组件,则将获得包含子目录的目录列表,但是该列表中可能会重复。因此,您需要对列表进行后处理,产生(作为第一近似值):

find ${base:-.} -type d |
sed 's%/[^/]*$%%' |
sort -u

查找在变量$base中列出的一个或多个目录下的所有目录,默认为当前目录,并打印其名称。该代码假定您没有名称中包含换行符的目录。如果这样做,则有修复程序,但是最好的解决方法是重命名目录。 sed命令删除最后一个斜杠及其后的所有内容。排序消除重复的条目。剩下的是包含子目录的目录列表。

嗯,或多或少。有一种退化的情况要考虑:列表中的顶级目录将被列出,无论它们是否具有子目录。修复起来有点困难。在删除结尾的资料之前,需要消除与find指定的目录完全匹配的所有输出行。因此,您需要类似:

{
printf '\\#^%s$#d\n' ${base:-.}
echo 's%/[^/]*$%%'
} > sed.script
find ${base:-.} -type d |
sed -f sed.script |
sort -u
rm -f sed.script

\\#^%s$#d假定您未在目录名称中使用#。如果您确实使用过它,那么您需要找到一个名称中不用的字符(也许是Control-A),并用它代替#。如果您绝对可以面对任何字符,那么当目录名称中出现某些晦涩的字符(例如Control-A)时,您需要做更多的工作。

[仍然存在问题:使用sed.script之类的固定名称作为临时文件名是不好的(出于多种原因,例如两个人试图在同一目录中同时运行脚本,尽管也可以有安全隐患),因此请使用mktemp创建一个临时文件名:

tmp=$(mktemp ${TMPDIR:-/tmp}/dircnt.XXXXXX)
trap "rm -f $tmp; exit 1" 0 1 2 3 13 15
{
printf '\\#^%s$#d\n' ${base:-.}
echo 's%/[^/]*$%%'
} > $tmp
find ${base:-.} -type d |
sed -f $tmp |
sort -u
rm -f $tmp
trap 0

这处理最常见的信号(HUP,INT,QUIT,PIPE,TERM),并删除临时文件,即使其中一个到达也是如此。

显然,如果您只想计算目录数,则可以通过wc -l用管道传输上述命令的输出以获取计数。


2
投票

您可以使用find命令:find . -type d -not -empty


0
投票
ls -1d */*/. | cut -d / -f1 | uniq
© www.soinside.com 2019 - 2024. All rights reserved.