include/exclude patterns to copy just certain files?

Bob Proulx bob at proulx.com
Sat Jul 3 23:25:05 GMT 2004


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


More information about the rsync mailing list