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.


I came up with the following solution.

# exclude system created files like .DS_Store, desktop.ini...

# 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"

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.