I have a directory A
with a large number of sub directories and files and want to get a list of all files named foo
that are inside of a directory in A
that matches *bar
. E.g.:
- Yes:
./goldbar/fiz/baz/foo
- Yes:
./leadbar/foo
- No:
./candy/figbar/foo
I have the some additional constraints:
- I must not descend into directories that don't match the
*bar
(this is a necessary optimization as it would take to long to scan those) - I can't allow the shell to do the glob expansion because it returns to many results: (i.e.
find *bar -type f -name foo
fails)
I think that the -path
flag would give me the results I need but I don't know if it fits the first of the above constraints.
Edit: Assume that there are n*10k directories in A
that match *bar
. i.e. anything that tries to build a command with all of them (as opposed to handling each one in tern) will fail.
I'm not sure how
-path
will handle the "do not descend into directories that don't match*bar
" requirement, and I'm too lazy to build an environment to find out.I do know the following will work on pretty much any *nix platform:
Additional weaseling of the
ls
/grep
bit may be required if you have plain files, sockets, etc. in your top-level directory, or if you want to revise your conditions a little.If you're looking for a solution purely with
find
, thenshould do the trick.
Try this - not sure how quick it will be though.
NOTE this doesn't work for Solaris 10 as it's find doesn't have
-maxdepth
I checked with strace and -path by itself does not avoid the unneded incursion into non-matched directories. This should do the job, though:
find . \( -name '.' \) -print -o \( ! -path '*directory_pattern*' \) -prune -o -name '*file_pattern*' -print
The
\(
and\)
s aren't actually needed on this particular case, but they add readability and would probably be needed if you used more complex expressions. Checked with strace and it seems to work, hope it helps.How about a regex version:
EDIT: Tweaked it with a cleaner one and terminating the line (so you're not matching fooble, foogasm, etc...)