rsync exclude a directory but include a subdirectory
Sometime it's just a detail.
Just change your include pattern adding a trailing / at the end of include pattern and it'll work:
rsync -avz --delete --include=specs/install/project1/ \ --exclude=specs/* /srv/http/projects/project/ \ user@server.com:~/projects/project
Or, in alternative, prepare a filter file like this:
$ cat << EOF >pattern.txt> + specs/install/project1/> - specs/*> EOF
Then use the --filter option:
rsync -avz --delete --filter=". pattern.txt" \ /srv/http/projects/project/ \ user@server.com:~/projects/project
For further info go to the FILTER RULES section in the rsync(1) manual page.
The other solution is not working here.
Reliable way
You have no choice but to manually descend for each level of your sub-directory. There is no risk to include unwanted files, as rsync doesn't include the files of included directories.
1) Create an include filter file, for instance "include_filter.txt":
+ /specs/+ /specs/install/+ /specs/install/project1/***- /specs/**
2) Run it:
rsync -avz --delete --include-from=include_filter.txt \ /srv/http/projects/project/ \ user@server.com:~/projects/project
- Don't forget the starting slash "/", otherwise you may match sub-directories named "**/specs/install/project1/".
- By choosing an include type filter (--include-from=FILE), the starting plus "+" signs are actually optional, as this is the default action with no sign. (You can have the opposite "-" by default with --exclude-from=FILE.)
- The double stars "**" means "any path"
- The triple stars "***" means "any path, including this very directory"
Easy way
You can start your filters "*/", allowing rsync to descend all your sub-levels. This is convenient but:
- All directories will be included, albeit empty. This can be fixed with the rysnc option -m, but then all empty dirs will be skipped.
1) Create an include filter file, for instance "include_filter.txt":
+ /**/+ /specs/install/project1/***- /specs/**
2) Run it:
rsync -avzm --delete --include-from=include_filter.txt \ /srv/http/projects/project/ \ user@server.com:~/projects/project
Note the added option -m.