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 .jpg
en el árbol completo, pero no estoy seguro de cómo limitarlo solo a las carpetas inferiores sin hacer algo como grep
enviar los resultados a filtrar por 111
// 222
, 333
lo 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 find
manualmente 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 2
basa 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 btrfs
o nilfs
cuyas 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