【问题标题】:List all directories not containing a subdirectoriy列出所有不包含子目录的目录
【发布时间】:2013-07-25 12:07:10
【问题描述】:

我的问题有解决方案

find . -type d -exec sh -c 'test $(find "$0" -maxdepth 1 -type d | wc -l) -eq 1' {} \; -print

我想知道是否有更好(更快)的方法来做到这一点。我真的不喜欢从“查找”另一个查找过程开始。

【问题讨论】:

标签: bash find


【解决方案1】:

man find 会列出一个选项:

   -links n
          File has n links.

您正在寻找仅包含两个链接的目录(即. 及其名称)。以下将返回没有子目录的目录:

find . -type d -links 2

普通 Unix 文件系统上的每个目录至少有 2 个硬链接:它的名称和它的 .(父目录)条目。此外,它的每个子目录(如果有)都有一个链接到该目录的.. 条目。

【讨论】:

  • find . -type d -links 2 的输出对于位于 ntfs 分区上的目录为空。对于 ext3 文件系统,此解决方案有效。
  • @finite 你是对的。但是,它会在本地文件系统上运行良好,这是 假设
  • 实际上这给出了正确的结果,但不是因为解释的原因。任何目录至少有 2 个硬链接(目录本身和.),任何子目录都将计数加 1(子目录内的..)。
  • @toro2k:创建一个只有一个文件的子目录,此命令不会列出该子目录。
  • 嗯...mkdir -p foo/bar/baz; touch foo/bar/baz/something; find foo -type d -links 2 返回foo/bar/baz
【解决方案2】:

只需稍加编码,以下命令也可以工作:

find . -type d|awk 'NR>1{a[c++]=$0; t=t $0 SUBSEP} END{for (i in a) {if (index(t, a[i] "/") > 0) delete a[i]} for (i in a) print a[i]}'

使其更具可读性:

find . -type d | awk 'NR > 1 {
   a[c++]=$0;
   t=t $0 SUBSEP
}
END {
   for (i in a) {
      if (index(t, a[i] "/") > 0)
         delete a[i]}
   for (i in a)
      print a[i]
}'

虽然在这个解决方案中它可能看起来需要更多编码,但在一个大目录中,这个基于 awk 的命令应该比嵌入式 find | wc 解决方案运行得快得多,如问题所示。

性能测试:

我在包含 15k+ 个嵌套子目录的目录上运行它,发现这个 awk 命令比 OP 的 find | wc 命令快得多(快 250-300%)。

【讨论】:

    猜你喜欢
    • 2016-02-11
    • 2011-08-05
    • 2011-11-09
    • 2011-11-09
    • 2021-01-05
    • 2012-11-14
    • 2020-08-19
    • 2012-09-02
    相关资源
    最近更新 更多