查找所有目录,不包含其他目录

u15*_*iq5 4 bash find

目前:

$ find -type d
./a
./a/sub
./b
./b/sub
./b/sub/dub
./c/sub
./c/bub
Run Code Online (Sandbox Code Playgroud)

我需要:

$ find -type d -not -contains -type d
./a/sub
./b/sub/dub
./c/sub
./c/bub
Run Code Online (Sandbox Code Playgroud)

如何排除包含其他(子)目录但不为空(包含文件)的目录?

Ted*_*gmo 5

您可以查看find只有 2 个(或更少)链接的叶目录,然后检查每个找到的目录是否包含一些文件。

像这样的东西:

# find leaf directories
find -type d -links -3 -print0 | while read -d '' dir
do
    # check if it contains some files
    if ls -1qA "$dir" | grep -q .
    then
        echo "$dir"
    fi
done
Run Code Online (Sandbox Code Playgroud)

或者干脆:

find -type d -links -3 ! -empty
Run Code Online (Sandbox Code Playgroud)

请注意,您可能需要在某些文件系统上使用该find选项-noleaf,例如 CD-ROM 或某些 MS-DOS 文件系统。不过,它在 WSL2 中没有它也能工作。

文件系统中,目录总是有 1 个链接,因此使用-links在那里不起作用。

一个慢得多但与文件系统无关的find基于版本:

prev='///' # some impossible dir

# A depth first find to collect non-empty directories
readarray -d '' dirs < <(find -depth -type d ! -empty -print0)

for dir in "${dirs[@]}"
do
    dirterm=$dir'/'

    # skip if it matches the previous dir
    [[ $dirterm == ${prev:0:${#dirterm}} ]] && continue

    # skip if it has sub directories
    [[ $(find "$dir" -mindepth 1 -maxdepth 1 -type d -print -quit) != '' ]] && continue

    echo "$dir"
    prev=$dir
done # add "| sort" if you want the same order as a "find" without "-depth"
Run Code Online (Sandbox Code Playgroud)