使用GNU find仅显示叶子目录

时间:2010-11-24 17:40:54

标签: bash shell find gnu

我正在尝试使用GNU find来查找不包含其他目录的目录,但可能包含也可能不包含常规文件。

到目前为止,我最好的猜测是:

find dir -type d \( -not -exec ls -dA ';' \)

但这只是给我一长串“。”

谢谢!

7 个答案:

答案 0 :(得分:71)

如果您的文件系统符合POSIX,则可以使用-links(即,目录中包含每个子目录的链接,来自其父目录的链接和指向self的链接,因此如果没有子目录,则计数为2个链接)。

以下命令应该执行您想要的操作:

find dir -type d -links 2

然而,它似乎不适用于Mac OS X(正如@Piotr所提到的)。这是另一个版本,速度较慢,但​​可以在Mac OS X上运行。它基于他的版本,并通过更正来处理目录名称中的空格:

find . -type d -exec sh -c '(ls -p "{}"|grep />/dev/null)||echo "{}"' \;

答案 1 :(得分:5)

我刚刚发现了另一个适用于Linux和Linux的解决方案。 macOS(没有find -exec)!

它涉及sort(两次)和awk

find dir -type d | sort -r | awk 'a!~"^"$0{a=$0;print}' | sort

说明:

  1. 按相反顺序对find输出进行排序

    • 现在你首先出现子目录,然后出现他们的父母
  2. 如果当前行是前一行的前缀,则使用awk省略行

    • (此命令来自answer here
    • 现在你淘汰了#34;所有父目录" (你和父母一起离开了)
  3. sort他们(所以它看起来像普通的find输出)
  4. 瞧!快速便携。

答案 2 :(得分:2)

由于某些不明原因,@ sylvian解决方案在mac os x上无效。所以我想出了一个更直接的解决方案。希望这会对某人有所帮助:

find . -type d  -print0 | xargs -0 -IXXX sh -c '(ls -p XXX | grep / >/dev/null) || echo XXX' ;

说明:

  • ls -p以'/'
  • 结束目录
  • 所以如果没有目录,(ls -p XXX | grep / >/dev/null)会返回0
  • -print0&& -0是使xargs处理目录名中的空格

答案 3 :(得分:0)

这个怎么样?它是便携式的,它不依赖于finnicky链接计数。但请注意,将find root/folder -type d | awk '{ if (length($0)<length(prev) || substr($0,1,length(prev))!=prev) print prev; prev=($0 "/") } END { print prev }' 放在尾随/。

的位置非常重要
NSTimeInterval time1 = [[NSDate date] timeIntervalSince1970];
unsigned long long bytesOfDownloading1 = 0;

答案 4 :(得分:0)

这是适用于Linux和OS X的解决方案:

find . -type d -execdir sh -c 'test -z "$(find "{}" -mindepth 1 -type d)" && echo $PWD/{}' \;

或:

struct HoldStuff {
  std::vector<StuffItem> items;
  std::set<StuffItem, StuffItemComparator> sorted_items;
}

答案 5 :(得分:0)

我的目录树中有一些名称奇怪的文件,它们使awk像 @AhmetAlpBalkan的答案。所以我采用了稍微不同的方法

  p=;
  while read c;
    do 
      l=${#c};
      f=${p:0:$l};
      if [ "$f" != "$c" ]; then 
        echo $c; 
      fi;
      p=$c; 
    done < <(find . -type d | sort -r) 

awk解决方案中一样,我进行反向排序。这样,如果目录路径是上一个匹配项的子路径,则可以轻松地辨别。

这里p是我以前的比赛,c是当前比赛,l是当前比赛的长度,f是第一个l上一个匹配的匹配字符。我只echo那些与上一场比赛的开始不符的匹配。

提供的awk解决方案的问题是,如果路径名在某些子目录的名称中包含诸如+之类的东西,则字符串开头的匹配似乎会引起混淆。这导致awk为我返回了一些误报。

答案 6 :(得分:0)

awk / sort管道比最初建议的in this answer更好,但是在很大程度上基于它:)无论路径是否包含,它都将更可靠地工作regex特殊字符与否:

find . -type d | sort -r | awk 'index(a,$0)!=1{a=$0;print}' | sort

请记住,awk字符串是1索引而不是0索引,如果您习惯使用基于C的语言,这可能很奇怪。

如果当前行在上一行中的索引为1(即从该行开始),则我们将其跳过,就像"^"$0的匹配项一样。