40

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

  • 数据
    • 公司1
      • 唯一文件夹1
      • 其他文件夹
      • ...
    • 公司2
      • 唯一文件夹1
      • ...
    • ...

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

  • 数据
    • 公司1
      • 唯一文件夹1
    • 公司2
      • 唯一文件夹1
    • ...

我知道这rsync对此非常有利。我尝试了“包含/排除”选项但没有成功。

例如我试过:

rsync -avzn --list-only --include '*/unique_folder1/**' --exclude '*' -e ssh user@server.com:/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. 但这很慢,有很多文件等。

4

4 回答 4

39

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

rsync -avzn --list-only --include 'company1/' --include 'company1/unique_folder1/***' --exclude '*' -e ssh user@server.com:/path/to/old/data/ /path/to/new/data

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


最后我们需要做的事情:

1.在服务器1上生成包含文件,所以它的内容将是(我用过lsawk):

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

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

rsync -avzn                                        \
      --list-only                                  \
      --include-from '/path/to/new/include.txt'    \
      --exclude '*'                                \
      -e ssh user@server.com:/path/to/old/data/    \
      /path/to/new/data
于 2013-03-29T10:49:16.483 回答
27

如果第一个匹配模式排除了一个目录,那么它的所有后代将永远不会被遍历。当您想包含一个深层目录,例如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='*'
于 2014-11-06T21:50:28.457 回答
6

在许多情况下更容易理解和实施的Andron 答案的替代方法是使用该--files-from=FILE选项。针对目前的问题,

rsync -arv --files-from='list.txt' old_path/data new_path/data

list.txt简单的在哪里

company1/unique_folder1/
company2/unique_folder1/
...

请注意,-r必须明确包含标志,因为--files-from会关闭-a标志的这种行为。在我看来,路径构造与其他 rsync 命令不同,因为匹配company1/unique_folder1//data/company1/unique_folder1/不匹配。

于 2020-12-26T08:46:04.730 回答
3

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

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

需要注意的重要事项:

  • 不要忘记/路径末尾的“”,否则您将在子目录中获得副本。
  • --include,的顺序--exclude很重要。
  • 与其他答案相反,以“ /”开头的不需要包含/排除参数,它们将自动附加到源目录(target/在示例中)。
  • 为了测试究竟会发生什么,我们可以使用--dry-run标志,正如其他答案所说。
  • --delete-excluded 将删除目标目录中的所有内容,除了我们特别包含的子目录。应该明智地使用它!因此,a--delete是不够的,它默认不删除远程端的排除文件(每隔一个,是的),它应该在普通的旁边--delete再次给出。
于 2019-04-12T23:02:57.027 回答