rsync --delete --files-from = list/dest /不会删除不需要的文件

dAn*_*jou 25 rsync

正如您在标题中看到的,我尝试将文件夹与文件列表同步.我希望这个命令会删除dest /不在列表中的所有文件,但事实并非如此.

所以我搜索了一下,现在知道,rsync不能这样做.

但我需要它,所以你知道有什么办法吗?

PS:列表是由python脚本创建的,因此可以想象你的解决方案使用了一些python代码.

编辑,让我们具体:

该列表如下所示:

/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
Run Code Online (Sandbox Code Playgroud)

和这样的命令:

rsync --delete --files-from=/tmp/list / /home/max/Desktop/foobar/
Run Code Online (Sandbox Code Playgroud)

这是有效的,但如果我删除一行,它不会在foobar /中删除.

编辑2:

rsync -r --include-from=/tmp/list --exclude=* --delete-excluded / /home/max/Desktop/foobar/
Run Code Online (Sandbox Code Playgroud)

那工作既不......

Sim*_*onJ 18

也许你可以使用包含模式列表代替,并使用--delete-excluded(顾名思义)?就像是:

rsync -r --include-from=<patternlistfile> --exclude=* --delete-excluded / dest/
Run Code Online (Sandbox Code Playgroud)

如果文件名可能包含通配符(*,?[),那么您可能需要修改Python以逃避它们:

re.sub("([[*?])", r"\\\1", "abc[def*ghi?klm")
Run Code Online (Sandbox Code Playgroud)

编辑:出于效率的原因,基于模式的匹配工作略有不同--files-from,因为它rsync不会递归到与排除模式匹配的目录中.因此,如果您的文件在/some/dir,/some/other/dir然后您的模式文件需要如下所示:

/some/
/some/dir/
/some/dir/file1
/some/dir/file2
/some/other/
/some/other/dir/
/some/other/dir/file3
...
Run Code Online (Sandbox Code Playgroud)

或者,如果所有文件都在同一目录中,那么您可以稍微重写该命令:

rsync -r --include-from=<patternlistfile> --exclude=* --delete-excluded /some/dir/ dest/
Run Code Online (Sandbox Code Playgroud)

然后你的模式变成:

/file1
/file2
Run Code Online (Sandbox Code Playgroud)

编辑:考虑一下,你可以用一种模式包含所有目录:

/**/
Run Code Online (Sandbox Code Playgroud)

但是你最终会得到整个目录树,dest/其中可能不是你想要的.但是将它与-m(修剪空目录)相结合应该可以解决这个问题 - 所以命令会结束如下:

rsync -m -r --delete-excluded --include-from=<patternfile> --exclude=* / dest/
Run Code Online (Sandbox Code Playgroud)

和模式文件:

/**/
/some/dir/file1
/some/other/dir/file3
Run Code Online (Sandbox Code Playgroud)

  • 这些文件是在子目录中吗?如果是这样,目录(及其父项)也需要在模式列表中,否则rsync甚至不会进入它们. (2认同)
  • 在这里工作正常(除了第一次错过-r之外-还会教我重新键入内容)。我希望您能检查手册页并根据您的情况调整我的命令,而不是盲目地复制粘贴;) (2认同)

Wil*_*ard 10

这不是解决方案,但是来到这里的人可能会觉得这很有用:从rsync 3.1.0开始,有一个--delete-missing-args参数可以在使用时同步两个目录时删除目标目录中的文件--files-from.您需要指定已删除的文件/tmp/list以及要复制的文件:

rsync --delete-missing-args --files-from=/tmp/list /source/dir /destination/dir
Run Code Online (Sandbox Code Playgroud)

有关更多详细信息,请参见手册页.

  • 看起来很有希望,但我误解了这个选项的作用。如果文件列在 --files-from 列表中但在源上找不到,它只会删除目标上的文件。 (4认同)

m4t*_*m4t 7

正如你解释的那样,命令

rsync -r --delete --files-from=$FILELIST user@server:/ $DEST/
Run Code Online (Sandbox Code Playgroud)

删除$ FILELIST中的条目时,不会删除目标中的内容.一个简单的解决方案是使用以下代码.

mkdir -p $DEST
rm -rf $TEMP
rsync -r --link-dest=$DEST --files-from=$FILELIST user@server:/ $TEMP/
rm -r $DEST
mv $TEMP $DEST
Run Code Online (Sandbox Code Playgroud)

这指示rsync使用空目标.link-dest-directory中已存在的文件是本地硬链接的,不会被复制.最后,旧目的地被新的目的地取代.如果$ DEST不存在,则第一个mkdir创建一个空的$ DEST,以防止rsync错误.(假定$ -variables携带到相应文件或目录的完整路径.)

硬链接有一些小的开销,但你不需要搞乱复杂的包含/排除策略.