rsync仅使用include选项复制某些类型的文件

时间:2012-06-20 01:09:37

标签: linux bash shell rsync

我使用以下bash脚本仅复制某些扩展名的文件(在本例中为* .sh),但它仍会复制所有文件。怎么了?

from=$1
to=$2

rsync -zarv  --include="*.sh" $from $to

6 个答案:

答案 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"
  1. 不要跳过任何目录
  2. 不要跳过任何.sh文件
  3. 跳过所有内容
  4. (示意性地,不要跳过任何内容,但是上面的规则可以阻止默认规则的发生。)

最后,--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

- /*