rsync copy over only certain types of files using include option rsync copy over only certain types of files using include option shell shell

rsync copy over only certain types of files using include option


I think --include is used to include a subset of files that are otherwise excluded by --exclude, rather than including only those files.In other words: you have to think about include meaning don't exclude.

Try instead:

rsync -zarv  --include "*/" --exclude="*" --include="*.sh" "$from" "$to"

For rsync version 3.0.6 or higher, the order needs to be modified as follows (see comments):

rsync -zarv --include="*/" --include="*.sh" --exclude="*" "$from" "$to"

Adding the -m flag will avoid creating empty directory structures in the destination. Tested in version 3.1.2.

So if we only want *.sh files we have to exclude all files --exclude="*", include all directories --include="*/" and include all *.sh files --include="*.sh".

You can find some good examples in the section Include/Exclude Pattern Rules of the man page


The answer by @chepner will copy all the sub-directories irrespective of the fact if it contains the file or not. If you need to exclude the sub-directories that dont contain the file and still retain the directory structure, use

rsync -zarv  --prune-empty-dirs --include "*/"  --include="*.sh" --exclude="*" "$from" "$to"


Here's the important part from the man page:

As the list of files/directories to transfer is built, rsync checks each name to be transferred against the list of include/exclude patterns in turn, and the first matching pattern is acted on: if it is an exclude pattern, then that file is skipped; if it is an include pattern then that filename is not skipped; if no matching pattern is found, then the filename is not skipped.

To summarize:

  • Not matching any pattern means a file will be copied!
  • The algorithm quits once any pattern matches

Also, something ending with a slash is matching directories (like find -type d would).

Let's pull apart this answer from above.

rsync -zarv  --prune-empty-dirs --include "*/"  --include="*.sh" --exclude="*" "$from" "$to"
  1. Don't skip any directories
  2. Don't skip any .sh files
  3. Skip everything
  4. (Implicitly, don't skip anything, but the rule above prevents the default rule from ever happening.)

Finally, the --prune-empty-directories keeps the first rule from making empty directories all over the place.