比较两个目录结构并删除目标位置中多余的文件和目录的最佳方法是什么?
我正在开发一个小型网络照片库应用程序。用户使用 FTP 添加和删除图像。我编写的网络图库软件可以动态创建新的缩略图,但不能处理删除操作。我想要做的是安排一个命令/bash 脚本以预定义的时间间隔处理此问题。
原始图像存储在/home/gallery/images/
相册中,并使用子目录进行组织。缩略图缓存在 中/home/gallery/thumbs/
,使用与图像目录相同的目录结构和文件名。
我尝试使用以下方法来实现这一点:
rsync -r --delete --ignore-existing /home/gallery/images /home/gallery/thumbs
如果所有缩略图都已缓存,那么它将正常工作,但不能保证会出现这种情况,当发生这种情况时,缩略图目录会将原始的全尺寸图像复制到其中。
我怎样才能最好地实现我想要做的事情?
答案1
我认为rsync
这不是最好的方法。我会使用如下的 bash 单行命令:
$ cd /home/gallery/thumbs && find . -type f | while read file;do if [ ! -f "../images/$file" ];then echo "$file";fi;done
如果此行命令生成了正确的文件列表,那么您可以修改它以运行一个rm
命令而不是一个echo
命令。
答案2
你--existing
也需要:
rsync -r --delete --existing --ignore-existing /home/gallery/images /home/gallery/thumbs
来自手册页:
--existing, --ignore-non-existing This tells rsync to skip creating files (including directories) that do not exist yet on the destination. If this option is combined with the --ignore-existing option, no files will be updated (which can be useful if all you want to do is delete extraneous files).
答案3
我必须传输大量数据和许多文件。我使用 msrsync 来并行化 rsync 流,效果很好,但您不能将 rsync 选项“--delete”与 msrsync 一起使用,因为多个流会发生冲突并尝试删除彼此的文件。所以我开始寻找删除文件的解决方案,并发现了这个问题。
我的最终解决方案以原始问题为例并利用以前的答案(Tom Shaw)是使用:
$ cd /home/gallery
$ find thumbs -type f | sed -e 's/^thumbs//' | xargs -P64 -I% sh -c 'if [ ! -f "images/$1" ]; then echo "rm thumbnails/$1"; fi' -- %
此处的目的是仅从 thumbnails/ 中删除 images/ 中不存在的文件。此解决方案可能会在 thumbnails 中留下 images 中不存在的空目录。
使用 xargs 可以将其并行化为“-P64”。
按照 Tom Shaw 的解决方案,我在解决方案中使用了 echo,以便您在实际删除文件之前检查结果是否符合预期。
我为那些可能需要处理数百万个文件并且拥有运行多个线程的资源的人发布了这个替代解决方案。