我使用以下bash脚本仅复制某些扩展名的文件(在本例中为* .sh),但它仍会复制所有文件。怎么了?
from=$1 to=$2 rsync -zarv --include="*.sh" $from $to
答案 0 :(得分:118)
我认为--include
用于包含--exclude
排除的文件子集,而不是仅包含这些文件。
换句话说:你必须考虑 include ,意思是不排除。
尝试改为:
rsync -zarv --include "*/" --exclude="*" --include="*.sh" "$from" "$to"
对于rsync 3.0.6或更高版本,需要按如下方式修改订单(请参阅注释):
rsync -zarv --include="*/" --include="*.sh" --exclude="*" "$from" "$to"
添加-m
标志将避免在目标中创建空目录结构。在3.1.2版中测试。
因此,如果我们只需要* .sh文件,我们必须排除所有文件--exclude="*"
,包含所有目录--include="*/"
并包含所有* .sh文件--include="*.sh"
。
您可以在man page
的包含/排除模式规则部分找到一些很好的示例答案 1 :(得分:38)
@chepner的答案将复制所有子目录,无论其是否包含该文件。如果您需要排除不包含该文件但仍保留目录结构的子目录,请使用
rsync -zarv --prune-empty-dirs --include "*/" --include="*.sh" --exclude="*" "$from" "$to"
答案 2 :(得分:13)
还有一个补充:如果你需要通过仅一个目录(没有递归)的扩展来同步文件,你应该使用这样的结构:
rsync -auzv --include './' --include '.ext' --exclude '*' /source/dir/ /destination/dir/
请注意第一个--include
中的点。 --no-r
在此结构中不起作用。
答案 3 :(得分:5)
这是手册页中的重要部分:
在构建要传输的文件/目录列表时,rsync依次根据包含/排除模式列表检查要传输的每个名称,然后执行第一个匹配模式:如果是排除模式,则该文件被跳过;如果是包含模式,则不跳过该文件名;如果找不到匹配的模式,则不会跳过文件名。
总结:
另外,以斜杠结尾的内容是匹配目录(例如find -type d
)。
让我们从上面解开这个答案。
rsync -zarv --prune-empty-dirs --include "*/" --include="*.sh" --exclude="*" "$from" "$to"
.sh
文件最后,--prune-empty-directories
禁止第一个规则在整个地方创建空目录。
答案 4 :(得分:1)
编写了这个方便的函数,并放入了我的bash脚本或~/.bash_aliases
。在安装了bash和awk
的Linux上测试了本地同步。有效
selrsync(){
# selective rsync to sync only certain filetypes;
# based on: https://stackoverflow.com/a/11111793/588867
# Example: selrsync 'tsv,csv' ./source ./target --dry-run
types="$1"; shift; #accepts comma separated list of types. Must be the first argument.
includes=$(echo $types| awk -F',' \
'BEGIN{OFS=" ";}
{
for (i = 1; i <= NF; i++ ) { if (length($i) > 0) $i="--include=*."$i; } print
}')
restargs="$@"
echo Command: rsync -avz --prune-empty-dirs --include="*/" $includes --exclude="*" "$restargs"
eval rsync -avz --prune-empty-dirs --include="*/" "$includes" --exclude="*" $restargs
}
--dry-run
)时,方便易用且可扩展。
selrsync 'tsv,csv' ./source ./target --dry-run
答案 5 :(得分:0)
如果有人寻找这个……
我只想同步特定的文件和文件夹,并设法通过以下命令来做到这一点:rsync --include-from=rsync-files
使用rsync文件:
my-dir/
my-file.txt
- /*