我有两个目录需要合并在一起。 这两个目录中的文件都是大文件(> = 500MB)。
我要存档的内容:对于源目录中的文件:如果目标目录中不存在,将其mv到目标目录(这是因为我们基本上正在创build一个新的硬链接并取消链接源文件)。 如果它存在于目标目录中,则将源文件复制到那里并除去源文件。
在Linux系统中合并目录最常见的方法是使用rsync和--remove-source-files选项。 但是这样做很慢,因为即使目标文件不存在,它也会执行复制操作。
任何更好的想法? 谢谢。
基本上你所描述的是移动文件覆盖的目的地,如果存在。 所以只要移动它们。
mv选项都是关于解决冲突的:
选一个:
-f force (always overwrite) -i interactive (ask whether to overwrite) -n no clobber (no overwrite)
这也很好:
-v verbose
否则,数据可能会丢失,并且/或者不清楚究竟发生了什么。
mv在同样的fs上也是优越的,因为它只是更新目录inode,文件不应该混淆。 另一件事情是,操作越大,出现软错误的可能性就越大。
有一种情况是mv失败。 以下是一些示例数据:
mkdir -p src/d dest/d touch src/d/f1 dest/d/f2
看看如何mv失败:
$ mv src/* dest/ mv: cannot move 'src/d' to 'dest/d': Directory not empty $ mv -f src/* dest/ mv: cannot move 'src/d' to 'dest/d': Directory not empty $ mv -fv src/* dest/ mv: cannot move 'src/d' to 'dest/d': Directory not empty $ mv -fvi src/* dest/ mv: overwrite 'dest/d'? y mv: cannot move 'src/d' to 'dest/d': Directory not empty $ mv -fvi -t dest/ src/* mv: overwrite 'dest/d'? y mv: cannot move 'src/d' to 'dest/d': Directory not empty
所以制作一个脚本文件:
vim supermove
这个例子没有检查错误(DISCLAIMER:适用于我,但是请testing它是否适用于您…也许在mv之前使用echo ),并且将覆盖具有相同path的文件。 它使用find来查找\; 这是非常低效的,但+并不正确的前面加上"$dest" 。 较早的版本会使一些没有前置path的dirs,而新版本的find会说:
find: In '-exec ... {} +' the '{}' must appear by itself, but you specified 'dest/{}'
你也许可以find一种方法来解决这个问题。 (花了几分钟时间,我正在移动的64K文件8TB)。 添加此内容:
#!/bin/bash src=$1 dest=$2 src=$(readlink -f "$src") dest=$(readlink -f "$dest") cd "$src" # also copy hidden files shopt -s dotglob # make dirs (missing old permission,acl,xattr data), and then mv the files time find * -type d -exec mkdir -p "$dest"/{} \; time find * -type f -exec mv {} "$dest"/{} \; # also copy permissions, acls, xattrs rsync -aAX "$src"/ "$dest"/
并使其可执行:
chmod +rx supermove
并运行它
./supermove src/ dest/
结果…之前:
$ find src dest src/ src/d src/d/f1 dest/ dest/d dest/d/f2
后:
$ find src dest src src/d dest dest/d dest/d/f1 dest/d/f2
现在src/应该只是空dirs。 如果是这样,你可以rm -r src清理。