¿Cómo puedo enumerar todos los archivos, pero sólo en directorios que no tienen subdirectorios?

¿Cómo puedo enumerar todos los archivos, pero sólo en directorios que no tienen subdirectorios?

Tengo un árbol de directorios en el que quiero buscar recursivamente todos los archivos de un determinado tipo (por ejemplo, todos .jpg), pero solo quiero enumerar estos archivos si están en la parte inferior de un árbol de directorios.

Como ejemplo, si mi árbol se parece a:

                          home
                          root
                   f1     f2     f3
                   f11    f22    f33
                   f111   f222   f333

y todas las carpetas tienen .jpg's, solo quiero enumerar las .jpg' en f111/ f222/ f333, y así sucesivamente, e ignorar las que están en las carpetas superiores.

Sé que puedo usar un comando de búsqueda (como find . -name "*.jpg") para obtener una lista de todos .jpgen el árbol completo, pero no estoy seguro de cómo limitarlo solo a las carpetas inferiores sin hacer algo como grepenviar los resultados a filtrar por 111// 222, 333lo cual no es realmente factible ya que tengo cientos de carpetas y no sé cuál podría ser el nombre de las carpetas del último nivel para todas ellas individualmente.

Respuesta1

Puedes hacer esto en dos pasos:

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

El primer comando enumera todos los directorios sin subdirectorios (ya que cada subdirectorio agrega uno al recuento de enlaces, mientras que un directorio vacío tiene dos). El segundo invoca findmanualmente cada uno de estos resultados.

Respuesta2

Un equivalente POSIX deLa solución de @TomHunt.

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

Se -links 2basa en la propiedad de algunos sistemas de archivos de que el número de enlaces de directorios (inicialmente 2 para la entrada en su padre y la .entrada en ellos mismos) aumenta en uno por cada subdirectorio (debido a la ..entrada en ellos). Sin embargo , algunos sistemas de archivos modernos como btrfso nilfscuyas estructuras son radicalmente diferentes no tienen esa propiedad.

Con zsh, podrías hacer algo como:

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

información relacionada