我在正确使用 rsync
语法时遇到问题,我想知道我的场景是否真的可以使用 rsync
处理。首先,我确认 rsync
在我的本地主机和远程主机之间运行良好。对目录进行直接同步是成功的。
这是我的文件系统的样子:
uploads/
1260000000/
file_11_00.jpg
file_11_01.jpg
file_12_00.jpg
1270000000/
file_11_00.jpg
file_11_01.jpg
file_12_00.jpg
1280000000/
file_11_00.jpg
file_11_01.jpg
file_12_00.jpg
我想要做的是仅在子目录中以“file_11_”开头的文件上运行 rsync,并且我希望能够只运行一个 rsync 作业来同步子目录中的所有这些文件。
这是我正在尝试的命令:
rsync -nrv --include="**/file_11*.jpg" --exclude="*" /Storage/uploads/ /website/uploads/
这会导致在我的试运行中将 0
个文件标记为传输。我尝试了 --include
和 --exclude
语句的各种其他组合,但要么继续没有结果,要么得到了一切,就好像没有设置包含或排除选项一样。
任何人都知道如何做到这一点?
问题是 --exclude="*"
表示排除(例如)1260000000/
目录,因此 rsync
永远不会检查该目录的内容,因此永远不会注意到该目录包含您的 --include
匹配的文件.
我认为最接近你想要的是:
rsync -nrv --include="*/" --include="file_11*.jpg" --exclude="*" /Storage/uploads/ /website/uploads/
(这将包括所有目录和匹配 file_11*.jpg
的所有文件,但不包括其他文件),或者 可能:
rsync -nrv --include="/[0-9][0-9][0-9]0000000/" --include="file_11*.jpg" --exclude="*" /Storage/uploads/ /website/uploads/
(相同的概念,但对它将包含的目录更加挑剔)。
rsync
包括排除模式示例:
"*" means everything
"dir1" transfers empty directory [dir1]
"dir*" transfers empty directories like: "dir1", "dir2", "dir3", etc...
"file*" transfers files whose names start with [file]
"dir**" transfers every path that starts with [dir] like "dir1/file.txt", "dir2/bar/ffaa.html", etc...
"dir***" same as above
"dir1/*" does nothing
"dir1/**" does nothing
"dir1/***" transfers [dir1] directory and all its contents like "dir1/file.txt", "dir1/fooo.sh", "dir1/fold/baar.py", etc...
最后要注意的是,不要依赖一开始用于评估路径的星号;像 "**dir"
(可以将它们用于单个文件夹或文件,但不能用于路径)并注意两个以上的星号不适用于文件名。
INCLUDE/EXCLUDE PATTERN RULES
部分的 rsync
联机帮助页中找到详尽但不那么直观的解释
这是我的“教人钓鱼”的答案:
Rsync 的语法绝对不直观,但值得理解。
首先,使用 -vvv 查看 rsync 的调试信息。
$ rsync -nr -vvv --include="**/file_11*.jpg" --exclude="*" /Storage/uploads/ /website/uploads/
[sender] hiding directory 1280000000 because of pattern *
[sender] hiding directory 1260000000 because of pattern *
[sender] hiding directory 1270000000 because of pattern *
这里的关键概念是 rsync 递归地为每个目录应用包含/排除模式。一旦第一个包含/排除匹配,处理就会停止。
它评估的第一个目录是 /Storage/uploads
。 Storage/uploads
有 1280000000/, 1260000000/, 1270000000/
个目录/文件。它们都不匹配 file_11*.jpg
以包含。它们都匹配 *
以排除。因此它们被排除在外,并且 rsync 结束。
解决方案是首先包含所有目录 (*/)。那么第一个 dir 组件将是 1260000000/、1270000000/、1280000000/,因为它们匹配 */。下一个 dir 组件将是 1260000000/。在 1260000000/ 中,file_11_00.jpg 匹配 --include="file_11*.jpg",因此被包含。等等。
$ rsync -nrv --include='*/' --include="file_11*.jpg" --exclude="*" /Storage/uploads/ /website/uploads/
./
1260000000/
1260000000/file_11_00.jpg
1260000000/file_11_01.jpg
1270000000/
1270000000/file_11_00.jpg
1270000000/file_11_01.jpg
1280000000/
1280000000/file_11_00.jpg
1280000000/file_11_01.jpg
https://download.samba.org/pub/rsync/rsync.1
--include="*/"
在包含您实际想要包含的文件的父 目录中的重要性。--include
必须在--exclude
之前-include="*/"
,但它仍然无法正常工作。看到这个答案,我的第一个想法是“这正是我正在做的事情!”。然后我注意到顺序不同。