![如何迁移目录结构的变化?](https://linux22.com/image/1348849/%E5%A6%82%E4%BD%95%E8%BF%81%E7%A7%BB%E7%9B%AE%E5%BD%95%E7%BB%93%E6%9E%84%E7%9A%84%E5%8F%98%E5%8C%96%EF%BC%9F.png)
我使用 rsync 更新我的数码照片和视频的远程备份。我有大约 100GB 的数据。
现在,我已经将我的媒体文件夹重新组织成一个更合乎逻辑的结构。手动完成,而不仅仅是使用一些脚本exiftool
。问题是,对于 rsync,远程目录看起来完全不同。如果我运行更新,它将删除实际存在的文件(尽管在另一个位置),之后它将再次上传相同的文件。
由于我的上传速度很慢,所以要花很长时间。
由于所有文件名都是唯一的,我认为可以编写一个脚本来根据本地文件夹重新排列远程文件夹。
有谁知道这个问题的解决方案吗?
答案1
选项 1:回到过去,阅读以下内容:http://lincolnloop.com/blog/2012/jan/6/detecting-file-moves-renames-rsync/ 这使用了一个技巧,即使用硬链接来优化操作(不过请注意,示例中省略了尾随的“/”,这可能与您习惯的不同)。如果您在重组之前有本地备份副本,您也许可以恢复并使用它(复杂之处在于能够根据需要创建硬链接副本)。
选项 2:如果您的文件或目录名称中没有空格/引号,并且不打算保留任何重复项,则可以创建一个像这样的快速而肮脏的复制/重命名脚本。
来源:
cd /wherever
find . -type f | xargs sha1sum | sort > /tmp/src.out
到达目的地
cd /wherever
find . -type f | xargs sha1sum | sort > /tmp/dst.out
将dst.out
文件复制到源,然后在源上执行:
join -j 1 /tmp/src.out /tmp/dst.out | while read sum src dst; do
if [ "$src" != "$dst" ]; then
echo mkdir -p $(dirname "$src")
echo cp -ipl "$dst" "$src"
fi
done > fixup.sh
这将输出一组命令,您可以在目标上的副本的顶级目录中mkdir/cp
运行这些命令( )。fixup.sh
确保脚本输出能够完成你要求它做的事情.cp -ipl
不会在未经提示的情况下进行覆盖,而是通过硬链接进行复制。后续操作rsync --delete ...
将删除旧文件,假设您想要一份相同的副本。rsync --dry-run ...
之后使用以确认任何剩余差异的程度。
(可以使用“ mv -i
”代替非破坏性的“ cp -ipl
”,从而节省重复和清理工作。)
如果您的文件/目录名称有问题,则需要对文件名进行一些中间处理,或者尝试以下解决方案之一:https://unix.stackexchange.com/questions/6411/any-way-to-sync-directory-structure-when-the-files-are-already-on-both-sides
更新:
如果您可以容忍命令行中出现的标点符号爆炸sed
:
find . -type f -print0 | xargs -0 sha1sum |
sed -re $'s/(^[0-9a-z]*) /\\1__/;
s/ /\\\\x20/g; s/\'/\\\\\'/g;
s/(^[0-9a-z]*)__/\\1 /;
s/ (.*)$/ $\'\\1\'/g;'
这将处理空格和单/双引号(尽管我们正在接近perl
正确的重载领域)。它使用 bash$''
构造来引用麻烦的字符串。