如何使用Rsync仅复制特定的子目录(多个目录中的相同名称)

问题描述 投票:28回答:3

我在服务器1上有这样的目录结构:

  • 数据 公司1 unique_folder1 other_folder ... Company2的 unique_folder1 ... ...

我希望在服务器2上复制此文件夹结构,但只复制unique_folder1的目录/子目录。即结果必须是:

  • 数据 公司1 unique_folder1 Company2的 unique_folder1 ...

我知道rsync对此非常好。我试过'包含/排除'选项但没有成功。

例如。我试过了:

rsync -avzn --list-only --include '*/unique_folder1/**' --exclude '*' -e ssh [email protected]:/path/to/old/data/ /path/to/new/data/

但是,结果,我没有看到任何文件/目录:

receiving file list ... done
sent 43 bytes  received 21 bytes  42.67 bytes/sec
total size is 0  speedup is 0.00 (DRY RUN)

怎么了?想法?


附加信息:我有两个服务器的sudo访问权限。我有一个想法 - 使用find命令和cpio一起复制到我需要的内容的新目录,然后使用Rsync。但这很慢,有很多文件等。

centos rsync centos6
3个回答
29
投票

我找到了原因。至于我 - 目前尚不清楚Rsync是否以这种方式运作。 所以正确的命令(仅适用于company1目录)必须是:

rsync -avzn --list-only --include 'company1/' --include 'company1/unique_folder1/***' --exclude '*' -e ssh [email protected]:/path/to/old/data/ /path/to/new/data

即我们需要包含每个父级company目录。当然,我们无法在命令行中手动编写所有这些company目录,因此我们将列表保存到文件中并使用它。


我们需要做的最后事情:

1.生成包含在服务器1上的文件,因此其内容将是(我使用过lsawk):

+ company1/  
+ company1/unique_folder1/***  
...  
+ companyN/  
+ companyN/unique_folder1/***  

2.Copy include.txt到服务器2并使用这样的命令:

rsync -avzn                                        \
      --list-only                                  \
      --include-from '/path/to/new/include.txt'    \
      --exclude '*'                                \
      -e ssh [email protected]:/path/to/old/data/    \
      /path/to/new/data

16
投票

如果第一个匹配模式排除了目录,则永远不会遍历其所有后代。如果要包含深层目录,例如company*/unique_folder1/**但排除其他所有*,你需要告诉rsync包括它的所有祖先:

rsync -r -v --dry-run                       \
    --include='/'                           \
    --include='/company*/'                  \
    --include='/company*/unique_folder1/'   \
    --include='/company*/unique_folder1/**' \
    --exclude='*'

你可以使用bash的大括号扩展来节省一些打字。在大括号扩展之后,以下命令与前一个命令完全相同:

rsync -r -v --dry-run --include=/{,'company*/'{,unique_folder1/{,'**'}}} --exclude='*'

0
投票

例如,如果您只想将target/classes/target/lib/同步到远程系统,请执行

rsync -vaH --delete --delete-excluded --include='classes/***' --include='lib/***' \
      --exclude='*' target/ user@host:/deploy/path/

需要注意的重要事项:

  • 不要忘记从pathes的末尾开始的“/”,否则你将获得副本到子目录。
  • --include--exclude的顺序很重要。
  • 与其他答案相反,从“/”开始,不需要包含/排除参数,它们将自动附加到源目录(示例中为target/)。
  • 为了测试,究竟会发生什么,我们可以使用--dry-run标志,正如其他答案所说。
  • --delete-excluded将删除目标目录中的所有内容,但我们明确包含的子目录除外。它应该明智地使用!由于这个原因,--delete是不够的,默认情况下它不会删除远程端的排除文件(每隔一个,是的),它应该再次在普通的--delete旁边给出。
© www.soinside.com 2019 - 2024. All rights reserved.