仅通过文件名与rsync同步文件,忽略目录

我试图将文件从系统A同步到系统B.但是,这些文件被重新组织在另一个目录结构中,这使得使用rsync变得困难。

有没有什么办法可以告诉rsync忽略目录并仅对文件名进行操作? 文件名是唯一的 – 目录不是。 目录结构不固定,所以我不能简单地replace它们。 我已经想过编写一个删除目录信息的脚本,但我不确定是否会引起其他问题。

其实,是的,我希望将目录结构扁平化。 给出答案,rsync可能不是我想要使用的。

我正在使用video,第三方创build一个目录结构(他们应该被允许在适当的时候改变目录结构)。 这些video需要同步到主文件系统。 文件名被同意不被更改。 因此,在两个系统上的“find。| rip-out-path”和diff之间的差异可能会起作用。 但我想知道是否rsync有一些神奇的标志忽略目录时recursion – 类似于补丁中的-p参数。

你搞砸了,或者更less。 虽然你可以告诉rsyncrecursion和各种各样的其他游戏,你不能告诉它在文件系统树中四处寻找在另一端find一个相同的文件。

我要说的是,你将不得不做的是在远端有一个小包装脚本,如果是一个裸文件,那么将返回文件的全限定path,然后迭代每个文件在本地,调用这个包装脚本来获取远程path,然后执行rsync one … file … at … a …

那当然,假设所有的文件甚至已经存在于远端……如果他们甚至不在那里,他们从哪里得到呢? 他们跳过了吗?

我会发现谁想出这个疯狂的文件存储scheme,并打破他们的手指。

解决从目录树中直接将所有文件直接移动到一个文件的最简单方法可能是使用find和-type和-exec选项。 -type选项将输出限制为特定types的目录条目(f代表文件,d代表目录等)。 -exec选项将find的名称(作为{})传递给带有选项的命令行。

一些例子如下:

 find /directory/top/ -type f -exec rsync {} desthost:/destdir find /directory/top/ -type f -exec scp {} desthost:/destdir 
 SOURCE_DIR=/path/to/lots/of/dirs/and/files LINK_PATH=/path/to/store/all/files/as/symlinks/in/single/directory DEST_PATH=/path/to/place/all/files/in/single/directory/with/no/child/directories find $SOURCE_DIR -type f -print0 | xargs -0 cp -s --target-directory=$LINK_PATH rsync -Lts $LINK_PATH/* $USER@$DEST_IP:$DEST_PATH 

那么rsync中的–fuzzy选项呢? 我不知道这是否会在你的情况下工作,但你可以试试看。

在一般情况下,我仍然坚持“指手画脚”的其他答案,但对于您的具体情况,我有一个不同的解决scheme,就我的理解而言:

  • 其他人有他们自己的东西副本,在他们select的任何crapot等级; 和
  • 你需要他们所有的文件,但组织成你自己的裂痕层次结构

我在想,你运行一个rsync到远程特定的目录(如/storage/.remotes/client1/等)为每个远程文件系统你正在同步,然后有一个脚本将文件名归一化到您自己的层次结构中(假设您可以通过algorithm描述您的组织scheme),以及在rsync完成符合链接到特定于客户端的远程存储位置之后运行的所有内容。 如果你不能通过algorithm来描述你想要的层次结构,那么我想你必须手工完成你的符号链接(或者至less在某种程度上人为的input,即使有工具支持)。

唯一的困难是如果远程重新排列他们的东西,但是你只是检测到现在断开的符号链接,find文件名的新位置(假设名称没有改变,只是位置)。

如果所有文件都在同一个文件系统上,那么将它们全部链接到源端的一个目录,然后rsync跨目录可能会更容易。 就像是:

 #!/bin/bash set -e mkdir flattened_dir find sourcedir1 sourcedir2 sourcedir3 -type f -exec ln -t flattened_dir/ {} + rsync -avP flattened_dir/ remote:destination/ rm -r flattened_dir 

PS如果find不支持+ ,则可以使用\;

与此类似,我想将文件从目录中提取出来,并使用它们的文件名将它们放在一个单一的目录中。 解决scheme是:

  find /directory/top/ -type f -exec rsync -av `basename {}` desthost:/destdir 

你也可以使用find中的其他标志来限制你想要的文件…也许你只想要JPG文件:

  find /directory/top/ -type f -name "*.JPG" -exec rsync -av `basename {}` desthost:/destdir 

您可以使用Bash globopt( ** )recursion匹配每个文件,如本文所述。

既然你只调用rsync一次,它应该比其他调用每个文件的命令(比如find ... -exec )的方法快得多。

如果在一次调用rsync的过程中给你一个好的批量大小的文件,你可以一次做一个目录。 所以像这样:

 find . -type d | while read dir; do rsync -a $dir/* user@host:flatdir; done