An mpd playlist looks like this:


Bob Dylan - The Times They Are A-Changin' [V0]/04. One Too Many Mornings.mp3
Bob Dylan - The Times They Are A-Changin' [V0]/01. The Times They Are A-Changin'.mp3/

Or it can be configured to store the full path:


/home/share/media/audio/Bob Dylan - The Times They Are A-Changin' [V0]/01. The Times They Are A-Changin'.mp3
/home/share/media/audio/Bob Dylan - The Times They Are A-Changin' [V0]/03. With God On Our Side.mp3

I want to rsync those files to /media/sdg/MUSIC. I want it to delete files from the destination if they get removed from the playlist.

I can not get the incantation right. I thought I had it last night, but when I reran it, it didn't work. I've tried every combination of include-from, exclude=*, etc. I can think of.


Here's the basic approach (see this rsync filter guide for more information):

  • include the files in the playlist;
  • include all directories (otherwise nothing would be copied), and exclude everything else;
  • delete non-synced files and empty directories

Thus (untested):

rsync -a --include-from=/path/to/syncrel.m3u --include='*/' --exclude='*' \
      --delete --delete-excluded --prune-empty-dirs \
      /home/share/media/audio/ /media/sdg/MUSIC

If your file names may contain one of the wildcard characters *?[, there's an added complication. You need to precede these characters with a backslash. And if there are backslashes in file names as well, you need to precede them with a backslash as well, but only if there are other wildcards. Here's a sed snippet to convert a list of file names to the expected format (you only need the first expression if there are no backslashes in the file names):

sed -e 's/[*?\[]/\\&/g' -e 's/[*?[]/&/' -e T -e 's/\\\\/\\/g'

Under bash, ksh or zsh, there's a convenient way to filter the file list before passing it to rsync:

rsync -a --include-from=<(</path/to/syncrel.m3u sed -e 's/[*?\[]/\\&/g') \
      --include='*/' --exclude='*' \
      --delete --delete-excluded --prune-empty-dirs \
      /home/share/media/audio/ /media/sdg/MUSIC
  • thanks! this works, but it is silently skipping songs in certain albums(even with -v). I think it's the square brackets in the directory name. Adding -s doesn't solve. (Can someone fix my comment? Or should this go somewhere else?) – tladuke Jun 1 '11 at 16:27
  • @tladuke: rsync is interpreting the [ as a pattern character. See my edited answer. (To remove your first comment, click the × button that appears when you hover the mouse above it.) – Gilles 'SO- stop being evil' Jun 1 '11 at 20:48
  • how have I never seen that before (that shell magic) – tladuke Jun 2 '11 at 4:14
  • adding --modify-window=1 because the destination is FAT and rsync re-syncs sometimes – tladuke Jun 10 '11 at 20:46
  • @Gilles I had to use sed -e 's/[*?\[]/\\\\&/g') to make the above work, otherwise it was skipping the files such as Album [2014]/01.hip-hop.mp3 – Pratyush Oct 27 '14 at 20:24

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.