3

An mpd playlist looks like this:

syncrel.m3u

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:

syncfull.m3u

/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.

Kevin
  • 40,767
sea chub
  • 205

1 Answers1

3

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?) – sea chub Jun 01 '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 01 '11 at 20:48
  • how have I never seen that before (that shell magic) – sea chub Jun 02 '11 at 04:14
  • adding --modify-window=1 because the destination is FAT and rsync re-syncs sometimes – sea chub 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