如何列出所有文件,但仅列出没有子目录的目录?

如何列出所有文件,但仅列出没有子目录的目录?

我有一个目录树,我想递归搜索某种类型的所有文件(例如 all .jpg),但我只想列出这些文件(如果它们位于目录树的底部)。

举个例子,如果我的树看起来像:

                          home
                          root
                   f1     f2     f3
                   f11    f22    f33
                   f111   f222   f333

并且所有文件夹都有.jpg,我只想列出//等.jpg中的,并忽略较高文件夹中的。f111f222f333

我知道我可以使用 find 命令(如find . -name "*.jpg")来获取整个树中所有内容的列表.jpg,但我不确定如何将其限制为仅最底部的文件夹,而不执行诸如grep“将结果添加到”之类的操作过滤111/ 222/333的这实际上并不可行,因为我有数百个文件夹,而且我不知道最后一级文件夹可能会为所有这些文件夹单独命名。

答案1

您可以分两步执行此操作:

find . -type d -links 2 -print0 | xargs -0 -I{} find {} -name \*.jpg

第一个命令列出没有任何子目录的所有目录(因为每个子目录都会在链接计数中添加 1,而空目录则有 2)。第二个find手动调用每个结果。

答案2

POSIX 等价于@TomHunt 的解决方案

find . -type d -links 2 -exec sh -c '
  find "$@" -type f -name "*.jpg"' sh {} +

-links 2依赖于某些文件系统的属性,即目录的链接计数(对于其父目录中的条目和自身中的条目最初为 2 )对于每个子目录(因为其中的条目).增加 1 。..一些现代文件系统,例如btrfsnilfs其结构完全不同,但不具有这样的属性。

使用zsh,您可以执行以下操作:

has_subdirs() {
  local l
  l=($REPLY/*(/DNoN[1]))
  (($#l))
}
dirs_without_subdirs=(**/*(DN^+has_subdirs))
jpgs=($^dirs_without_subdirs/*.jpg(ND.))
(($#jpgs)) && printf '%s\n' $jpgs

相关内容