che*_*ner 150
我认为--include
用于包含被其他方式排除的文件子集--exclude
,而不是仅包括那些文件.换句话说:你必须考虑包含意义不要排除.
尝试改为:
rsync -zarv --include "*/" --exclude="*" --include="*.sh" "$from" "$to"
Run Code Online (Sandbox Code Playgroud)
对于rsync 3.0.6或更高版本,需要按如下方式修改订单(请参阅注释):
rsync -zarv --include="*/" --include="*.sh" --exclude="*" "$from" "$to"
Run Code Online (Sandbox Code Playgroud)
添加-m
标志将避免在目标中创建空目录结构.在3.1.2版中测试.
因此,如果我们只需要*.sh文件,我们必须排除所有文件--exclude="*"
,包括所有目录--include="*/"
并包含所有*.sh文件--include="*.sh"
.
您可以在手册页的"包含/排除模式规则"部分中找到一些很好的示例
Wan*_*ind 43
@chepner的答案将复制所有子目录,无论它是否包含该文件.如果您需要排除不包含该文件但仍保留目录结构的子目录,请使用
rsync -zarv --prune-empty-dirs --include "*/" --include="*.sh" --exclude="*" "$from" "$to"
Run Code Online (Sandbox Code Playgroud)
Ser*_*sak 13
还有一个补充:如果你只需要在一个目录中通过扩展来同步文件(没有递归),你应该使用这样的结构:
rsync -auzv --include './' --include '.ext' --exclude '*' /source/dir/ /destination/dir/
Run Code Online (Sandbox Code Playgroud)
请注意第一个中的点--include
.--no-r
在这种结构中不起作用.
这是手册页中的重要部分:
构建要传输的文件/目录列表后,rsync会根据包含/排除模式列表依次检查要传输的每个名称,然后执行第一个匹配模式:如果是排除模式,则该文件为跳过 如果是包含模式,则不跳过该文件名;如果找不到匹配的模式,则不跳过文件名。
总结一下:
另外,以斜杠结尾的东西是匹配目录(就像find -type d
这样)。
让我们从上面分开这个答案。
rsync -zarv --prune-empty-dirs --include "*/" --include="*.sh" --exclude="*" "$from" "$to"
Run Code Online (Sandbox Code Playgroud)
.sh
文件最后,--prune-empty-directories
保持第一条规则不要在各处创建空目录。