Linux – Rsync only certain directories and only certain sub-directories within them

linuxrsync

In /opt I have many different directories, some of which contain _pkg_linux_deb_ or _pkg_android_apk_ in the middle of their name. Those directories also contain many sub-directories, one of which is lastSuccessful which in turn contains archive as its own sub-directory. I want the files from those these archive sub-directories to be rsync'ed, retaining the whole directory structure, e.g. foo_pkg_linux_deb_bar/lastSuccessful/archive/dir1/dir2/dirN/foo.ext

Here is the rule I came up with, but it doesn't seem to work:

rsync -rnvm --include='/*(_pkg_linux_deb_|_pkg_android_apk_)*/lastSuccessful/archive/***' --exclude='*' /opt/ dest/

The following uses bash's expansion and it does work, but the destination doesn't contain the whole directory structure, it's missing *{_pkg_linux_deb_,_pkg_android_apk_}*/lastSuccessful/archive/ directories, putting only the contents of archive/ into dest/

rsync -rnvm /opt/*{_pkg_linux_deb_,_pkg_android_apk_}*/lastSuccessful/archive/ dest/

Best Answer

The main problem is that as rsync recursively descends through a folder hierarchy, it only enters directories that match its filter rules. So, in your first example, rsync never gets to a lastSuccessful directory, as the rule excludes the directory above it!

Instead you need to do something like this:

rsync -rnvm --include='/*_pkg_linux_deb_*/' --include='/*_pkg_android_apk_*/' --include='lastSuccessful/' --include='archive/***' --exclude='*' /opt/ dest/
Related Question