Rsync selected subdirectories only

rsync

I want to rsync a part of my music library from external drive to my audio player.

Generally speaking, say, there is a $source and $target directories, and a text file $subdirs with a list of sub-directory paths relative to $source of which I want to exclusively (–delete) rsync to $target preserving their directory tree structure (–relative).

My code my_sync.sh looks like:

rsync -rR --include-from=$subdirs --exclude="/*" --delete --delete-excluded $source/./ $target

The problem is, however, this only works for sub-dirs that are immediately located under $source (/dir/*.mp3), whereas nested sub-dirs (i.e. /dir1/dir2/…) are getting omitted.

Best Answer

I came up with the following solution.

# exclude system created files like .DS_Store, desktop.ini...
arg="-C
"

# project each "$path" to "/$path/**" and concat 'em all
while read line || [[ -n $line ]]; do
    arg+="+ /$line/**
"
done < $subdirs

# */ - includes each folder so that rsync traverses the whole tree,
# *  - excludes everything else
arg+="+ */
- *"

# -m - excludes "empty" dirs that we used to traverse the tree
echo "$arg" | rsync -rmhvn -f ". -" --delete-excluded --info=PROGRESS2 --size-only $source/./ "$target"
Related Question