Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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.

share|improve this question
up vote 3 down vote accepted

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
share|improve this answer
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 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 posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.