Skip to main content
1 of 5
Kusalananda
  • 355.8k
  • 42
  • 735
  • 1.1k

Not using find, but globbing in the zsh shell:

$ setopt NULL_GLOB
$ printf '%s\n' **/foo/*(.)
a/b/c/foo/z
a/b/foo/y
a/foo/x
foo/w

This uses the ** glob, which matches "recursively" down into directories, to match any directory named foo in the current directory or below, and then *(.) to match any regular file in those foo directories. The (.) at the end of that is a glob qualifier that restricts the pattern from matching anything but regular files.

In bash:

shopt -s globstar nullglob

for pathname in **/foo/*; do
    [[ -f "$pathname" ]] && printf '%s\n' "$pathname"
done

I set the nullglob option in bash (and NULL_GLOB in zsh) to remove the pattern completely in case it does not match anything. The globstar shell option enables the use of ** in bash (this is enabled by default in zsh).

Since bash does not have the glob qualifiers of zsh, I'm looping over the pathnames that the pattern matches and test each match to see if it's a regular file before printing it.

Kusalananda
  • 355.8k
  • 42
  • 735
  • 1.1k