How can I rsync a set of subdirectories?
Solution 1:
Possibility 1
Using the shell expansion1 instead of rsync
's filter rules, you can do as follows:
a. To include all bin
dirs in the top_dir
hierarchy:
rsync -av -R top_dir/**/bin/ destination_path
Here -R
is a rsync2 parameter standing for relative. man rsync
explains it as
Use relative paths. This means that the full path names specified on the command line are sent to the server rather than just the last parts of the filenames. This is particularly useful when you want to send several different directories at the same time.
but in essence it means that the directory structure is preserved.
**
is a shell globbing pattern and searches recursively for directories named bin
under top_dir
. So with the above example the command line gets expanded to:
rsync -av -R top_dir/proj1/bin/ top_dir/proj2/bin/ destination_path
b. If you only want to include bin
dirs one level below the project dir, just use a single *
(that works with "ancient" shells too!):
rsync -av -R top_dir/*/bin/ destination_path
1 You need a recent bash version (>4) and activate recursive globbing via shopts -s globstar
. With zsh recursive globbing is default.
2 rsync version v3.2.3 protocol version 31 on Linux.
Possibility 2
Only using rsync's filter rules you need:
a. To include all bin
dirs in the top_dir
hierarchy:
rsync -av -m --include='**/' --include='**/bin/**' --exclude='*' top_dir/ destination_path
The first include
rule might not be obvious3 but guarantees that all directories (note the trailing /
) are searched, the second adds everything in bin
directories, and the exclude
rule excludes everything else. -m
makes sure that empty directories are not copied.
b. To include only one level below the project dir:
rsync -av -m --include='/*/' --include='/*/bin/***' --exclude='*' top_dir/ destination_path
Using ***
syntax of rsync >= 2.6.7. The leading /
in the patterns represent top_dir
, otherwise the patterns are matched against the end of the file path.
3 Search for /some/path/this-file-will-not-be-found
in man rsync