如何仅列出给定路径中没有子文件夹的文件夹?

如何仅列出给定路径中没有子文件夹的文件夹?

问题:我已经给出了目录结构

├── kat11
│   ├── kat21
│   │   └── Dokument\ bez\ nazwy
│   └── kat22
│       ├── kat31
│       │   └── Dokument\ bez\ nazwy
│       └── kat32
│           └── Dokument\ bez\ nazwy
├── kat12
│   └── kat21
│       └── Dokument\ bez\ nazwy
├── kat13
│   └── Dokument\ bez\ nazwy
└── kat14
    └── Kat21
        └── Kat32
            └── Dokument\ bez\ nazwy

我只想列出所有具有完整路径的子文件夹。

例如

1. /kat14/kat21/kat32/Dokument\ bez\ nazwy
2. /kat11/kat22/kat31/Dokument\ bez\ nazwy
3. /kat11/kat22/kat32/Dokument\ bez\ nazwy
4. /kat12/kat21/Dokument\ bez\ nazwy

答案1

在一个小的python脚本中:

 #!/usr/bin/env python3
import os
import sys

src = sys.argv[1]
for root, dirs, files in os.walk(src):
    for dr in dirs:
        directory = root+"/"+dr
        if len([sub for sub in os.listdir(directory) \
                if os.path.isdir(directory+"/"+sub)]) == 0:
            print(directory)

使用它

  • 将其复制到空文件中,另存为count_empty.py
  • 使用目标目录作为参数运行它:

    python3 /path/to/count_empty.py '<source_directory>'
    

怎么运行的

  • python遍历os.walk()目录和子目录
  • 线路

    if len([sub for sub in os.listdir(directory) if os.path.isdir(directory+"/"+sub)]) == 0:
    

    随后计算子目录在每个子目录上。如果为零(无子目录),则打印目录及其路径。

在我的桌面上的一个简单的包文件夹上进行测试:

$ '/home/jacob/Bureaublad/pscript_5.py' '/home/jacob/Bureaublad/0.5.3' 
/home/jacob/Bureaublad/0.5.3/nonotifs-0.5.3/manpages
/home/jacob/Bureaublad/0.5.3/nonotifs-0.5.3/miscellaneous
/home/jacob/Bureaublad/0.5.3/nonotifs-0.5.3/icon
/home/jacob/Bureaublad/0.5.3/nonotifs-0.5.3/code
/home/jacob/Bureaublad/0.5.3/nonotifs-0.5.3/debian/source

答案2

简单find就足够了:

find /path/to/dir -type d -empty

例如:

$ tree foo
foo
├── 1
│   ├── 1
│   ├── 2
│   └── 3
├── 2
│   ├── 1
│   ├── 2
│   └── 3
└── 3
    ├── 1
    ├── 2
    └── 3

12 directories, 0 files
$ find foo -type d -empty
foo/2/2
foo/2/3
foo/2/1
foo/3/2
foo/3/3
foo/3/1
foo/1/2
foo/1/3
foo/1/1
$ touch foo/1/1/a foo/2/1/a foo/3/1/a 
$ find foo -type d -empty            
foo/2/2
foo/2/3
foo/3/2
foo/3/3
foo/1/2
foo/1/3

如果这些目录可以包含文件,那么这会更好,但成本较高:

find foo -type d -exec sh -c 'find "$0" -mindepth 1 -type d -printf z | grep -q z || printf "%s\n" "$0"' {} \;

此 Stack Overflow 帖子有一个相当巧妙的解决方案:

find /path/to/dir -type d -links 2

因为没有子目录的目录只有两个硬链接,一个是其父目录,一个是其自身目录。

这个问题,用不同的措辞,之前在 Stack Overflow、Super User 和 Unix & Linux 上都已经被问过:

答案3

免责声明:我是生皮相对湿度) (看https://github.com/raforg/rawhide)。

此解决方案仅适用于非 btrfs 文件系统:

find . -type d -links 2

使用的解决方案寻找在 btrfs 上运行非常复杂:

find . -type d \
    \( -exec sh -c 'find "$1" -mindepth 1 -maxdepth 1 -type d -print0 | grep -cz "^" >/dev/null 2>&1' _ {} \; -o -print \)

还有一个替代方案寻找称为生皮相对湿度) 这使得这变得更容易:

rh 'd && "[ $(rh -red -- %S | wc -l) = 0 ]".sh'

稍微短一点/快一点的版本是:

rh 'd && "[ -z \"$(rh -red -- %S)\" ]".sh'

上述命令搜索目录,然后列出它们的子目录,并且仅在没有子目录时才匹配(第一个命令通过计算输出的行数,第二个命令通过检查每个目录是否有任何输出)。

如果你不需要对 btrfs 的支持,那么它更像是寻找但更短:

rh 'd && nlink == 2'

对于在所有文件系统上尽可能高效地工作的版本:

rh 'd && (nlink == 2 || nlink == 1 && "[ -z \"$(rh -red -- %S)\" ]".sh)'

在普通(非 btrfs)文件系统上,此方法无需为每个目录添加任何额外进程,但在 btrfs 上则需要。如果您混合使用包括 btrfs 在内的不同文件系统,这可能是最佳选择。

相关内容