Como posso listar todos os arquivos, mas apenas em diretórios que não possuem subdiretórios?

Como posso listar todos os arquivos, mas apenas em diretórios que não possuem subdiretórios?

Eu tenho uma árvore de diretórios na qual desejo pesquisar recursivamente todos os arquivos de um determinado tipo (por exemplo, todos .jpg), mas só quero listar esses arquivos se eles estiverem na parte inferior de uma árvore de diretórios.

Por exemplo, se minha árvore se parecer com:

                          home
                          root
                   f1     f2     f3
                   f11    f22    f33
                   f111   f222   f333

e todas as pastas têm .jpg's, quero apenas listar os .jpg' em f111/ f222/ f333e assim por diante, e ignorar os que estão nas pastas superiores.

Eu sei que posso usar um comando find (como find . -name "*.jpg") para obter uma listagem de todos .jpgem toda a árvore, mas não tenho certeza de como limitá-lo apenas às pastas inferiores sem fazer algo como grepenviar os resultados para filtrar por 111/ 222/ 333's, o que não é realmente viável, pois tenho centenas de pastas e não sei como as pastas de último nível podem ser nomeadas para todas elas individualmente.

Responder1

Você pode fazer isso em duas etapas:

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

O primeiro comando lista todos os diretórios sem nenhum subdiretório (já que cada subdiretório adiciona um à contagem de links, enquanto um diretório vazio possui dois). O segundo invoca findmanualmente cada um desses resultados.

Responder2

Um equivalente POSIX deA solução do @TomHunt.

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

O -links 2depende da propriedade de alguns sistemas de arquivos de que a contagem de links de diretórios (inicialmente 2 para a entrada em seu pai e a .entrada em si) aumenta em um para cada subdiretório (por causa da ..entrada neles). Alguns sistemas de arquivos modernos, como btrfsou nilfscujas estruturas são radicalmente diferentes, não possuem essa propriedade.

Com zshvocê poderia fazer 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

informação relacionada