I want to transfer N files from a remote system, using a pattern:

ssh remote ls target/

I only want the 2014-07* files. My attempts so far:

rsync -a --dry-run --verbose --include="2014-07-*" remote:target .
# transfers everything

rsync -a --dry-run --verbose --include="2014-07-*" --exclude="*" remote:target .
# transfers nothing

rsync -a --dry-run --verbose --exclude="*" --include="2014-07-*" remote:target .
# transfers nothing

rsync -a --dry-run --verbose --include="*/2014-07-*" --exclude="*" remote:target .
# transfers nothing

rsync -a --dry-run --verbose --include="***/2014-07-*" --exclude="*" remote:target .
# transfers nothing

I know I can use --files-from to indicate which files exactly I want, but it's a pain to do.

I never understood how to correctly use include/exclude to do what I want. The man page states:

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.

Reading this, I presumed that if include was first, and the filename matched, then then "filename is not skipped" part would kick in. Apparently, I'm wrong.

Further down in the man page, I see:

Note that, when using the --recursive (-r) option (which is implied by -a), every subcomponent of every path is visited from the top down, so include/exclude patterns get applied recursively to each subcomponent’s full name

Since I used --recursive, did that cause . to be skipped, because of the global exclude?

How do I transfer a subset of files using include and exclude patterns?


While you can use include and exclude, I think this would be a simpler solution:

rsync -a --dry-run --verbose remote:'target/2014-07*' .

The reason your include/exclude variant doesn't work is that rsync never descends into the target directory since it is excluded by the * pattern and not matched by the include pattern (which only matches files in target, not target itself). For include/exclude to work you would have to do something like

rsync -a --dry-run --verbose --include=target --include='target/2014-07-*' --exclude='*' remote:target .

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.