Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

rsync --delete --files-from=list / dest/ does not delete unwanted files

Tags:

rsync

As you can see in the title I try to sync a folder with a list of files. I hoped that this command would delete all files in dest/ that are not on the list, but it didn't.

So I searched a little bit and know now, that rsync can't do this.

But I need it, so do you know any way to do it?

PS: The list is created by a python script, so it is imaginable that your solution uses some python code.

EDIT, let's be concrete:

The list looks like this:

/home/max/Musik/Coldplay/Parachutes/Trouble.mp3 /home/max/Musik/Coldplay/Parachutes/Yellow.mp3 /home/max/Musik/Coldplay/A Rush of Blood to the Head/Warning Sign.mp3 /home/max/Musik/Coldplay/A Rush of B-Sides to Your Head/Help Is Around the Corner.mp3 /home/max/Musik/Coldplay/B-Sides (disc 3)/Bigger Stronger.mp3 

and the command like this:

rsync --delete --files-from=/tmp/list / /home/max/Desktop/foobar/ 

This works, but if I delete a line, it is not deleted in foobar/.

EDIT 2:

rsync -r --include-from=/tmp/list --exclude=* --delete-excluded / /home/max/Desktop/foobar/ 

That works neither ...

like image 899
dAnjou Avatar asked Nov 28 '09 22:11

dAnjou


People also ask

Does rsync delete files in destination?

In its simplest form, the rsync command will copy files from the file source to the file destination. It will not remove files on the destination side that aren't on the source and it won't recreate all of the metadata (e.g., ownership and group details) unless your rsync command includes just the right set of options.

How do I delete files after rsync?

For removing the files from the source after the transfer, the rsync command provides the –remove-source-files option.


1 Answers

Perhaps you could do this using a list of include patterns instead, and use --delete-excluded (which does as the name suggests)? Something like:

rsync -r --include-from=<patternlistfile> --exclude=* --delete-excluded / dest/ 

If filenames are likely to contain wildcard characters (*, ? and [) then you may need to modify the Python to escape them:

re.sub("([[*?])", r"\\\1", "abc[def*ghi?klm") 

Edit: Pattern-based matching works slightly differently to --files-from in that rsync won't recurse into directories that match the exclude pattern, for reasons of efficiency. So if your files are in /some/dir and /some/other/dir then your pattern file needs to look like:

/some/ /some/dir/ /some/dir/file1 /some/dir/file2 /some/other/ /some/other/dir/ /some/other/dir/file3 ... 

Alternatively, if all files are in the same directory then you could rewrite the command slightly:

rsync -r --include-from=<patternlistfile> --exclude=* --delete-excluded /some/dir/ dest/ 

and then your patterns become:

/file1 /file2 

Edit: Thinking about it, you could include all directories with one pattern:

/**/ 

but then you'd end up with the entire directory tree in dest/ which probably isn't what you want. But combining it with -m (which prunes empty directories) should solve that - so the command ends up something like:

rsync -m -r --delete-excluded --include-from=<patternfile> --exclude=* / dest/ 

and the pattern file:

/**/ /some/dir/file1 /some/other/dir/file3 
like image 112
SimonJ Avatar answered Sep 18 '22 21:09

SimonJ