rsync include a certain "pattern" but exclude everything and preserve directories

find . -name foo | rsync -a --files-from=- . example.com:/tmp/

http://lists.samba.org/archive/rsync/2004-July/009975.html

(This is why linux/FOSS is great...)

I am attempting to copy only certain files down a directory tree.  I
know which files I want.  I could generate a file of just those with
'find'.  But having read the docs I have been trying to use the
--include and --exclude patterns to have rsync pick the right files
itself.  But I can't figure it out.  I am suspecting that I can't do
what I want to do.


Source example, this is what I have, foos and bars are files:

  dir1/a1/foo
 dir1/a2/foo
 dir1/a3/bar
 dir1/bar
 dir2/a1/foo
 dir2/a2/foo
 dir2/a3/bar
 dir2/bar

Destination example, this is what I want, just the foos:

 dir1/a1/foo
 dir2/a1/foo

Here is how I am trying to do it.

 rsync -a --include '**/a1/foo' --exclude "*" . example.com:/tmp/

But that does not match any files.  "0 files to consider" is the
result.  The man page has an example with --include "*/".

 rsync -a --include '*/' --include '**/a1/foo' --exclude "*" . example.com:/tmp/

That does too much and creates all of the directories even if there is
no file "foo" in the directory.  That is, in my example above all of
the */a2 directories are also copied.

Can anyone think of a way to do this?

The actual source directories are relatively large with 20k total
files or so in a deep hiearchy tree.  So expanding them on the command
line is not good since it will frequently exceed ARG_MAX.
Conceptually something like the following would work if the directory
was not too big and I could also line up the destination to match the
source.

 rsync -a $(find . -name foo -print) example.com:/tmp/  # bad example

 for file in $(find . -name foo -print); do  # another bad example
   dirname=$(dirname $file)
   rsync -a $file example.com:$dirname/  # 20k times seconds per ssh...
 done

That is just very, very slow.  I can almost use fsh but just the same
it would be much cleaner to do this entirely within rsync.

Thanks
Bob