How do you recursively specify all non-directory files in a directory in Bash?

How do you recursively specify all non-directory files in a directory in Bash?

Suppose I had a directory, e.g. animals, structured like:

animals
├── ant.pdf
├── cat
│   ├── ragdoll.txt
│   └── sphinx.png
├── dog
│   ├── labrador.jpg
│   └── pitbull.mp3
├── rat
│   └── labrat.gif
└── shark.java

And I wanted a Bash array consisting of "ant.pdf", "ragdoll.txt", "sphinx.png", "labrador.jpg", "pitbull.mp3", "labrat.gif", "shark.java", i.e. all the end nodes of this tree (not including any empty subdirectories). I would want to follow any subdirectories recursively with no maximum depth, or in practice no reasonable maximum depth i.e. one so high that it wouldn't be expected to be reached in a user's files.

What would be the best way to do this? I've got

files=(animals/*)

(replacing animals with whatever the directory is, of course)

which would give me an array of "ant.pdf", "cat", "dog", "rat", "shark.java", but not "ragdoll.txt" etc from the subdirectories, and I also don't want the subdirectories themselves to be in the array.

Answer

In the process of writing this post, I found the answer.

find "$directory" -type f

from GNU find, is exactly what I was looking for.

In terms of getting this into an array, you could use readarray:

readarray -t files < <(find "$directory" -type f)

Enjoyed this article?

Check out more content on our blog or follow us on social media.

Browse more articles