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

piah890a  于 2023-03-09  发布在  Shell
关注(0)|答案(7)|浏览(121)

我使用下面的bash脚本只复制特定扩展名的文件(在本例中是 *.sh),但是它仍然复制所有文件。

from=$1
to=$2

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

hwazgwia1#

我认为--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 pageInclude/Exclude Pattern Rules部分找到一些很好的示例

n9vozmp4

n9vozmp42#

@chepner的回答将复制所有的子目录,无论它是否包含文件。如果您需要排除不包含文件的子目录,但仍然保留目录结构,请使用

rsync -zarv  --prune-empty-dirs --include "*/"  --include="*.sh" --exclude="*" "$from" "$to"
n6lpvg4x

n6lpvg4x3#

下面是手册页中的重要部分:
在构建要传输的文件/目录列表时,rsync会依次对照include/exclude模式列表检查要传输的每个名称,并对第一个匹配的模式执行操作:如果是排除模式,则跳过该文件;如果是包含模式,则不跳过文件名;如果没有找到匹配的模式,则不跳过该文件名。
总结如下:

  • 不匹配任何模式意味着文件将被复制!
  • 任何模式匹配后,算法将退出

此外,以斜杠结尾的内容是匹配目录(如find -type d)。
让我们从上面分析一下这个答案。

rsync -zarv  --prune-empty-dirs --include "*/"  --include="*.sh" --exclude="*" "$from" "$to"

1.不跳过任何目录
1.不要跳过任何.sh文件
1.跳过所有内容
1.(隐含地说,不要跳过任何内容,但是上面的规则阻止了默认规则的发生。)
最后,--prune-empty-directories防止第一条规则使空目录到处都是。

0h4hbjxa

0h4hbjxa4#

还有一点:如果你需要到同步文件由它的扩展名在一个目录仅仅(没有递归)你应该使用一个结构象这样:

rsync -auzv --include './' --include '*.ext' --exclude '*' /source/dir/ /destination/dir/

请注意第一个--include中的点。--no-r在此构造中不起作用。

    • 编辑:**

感谢www.example.com的宝贵意见!gbyte.co for the valuable comment!

    • 编辑:**

-uzv标志与这个问题没有直接关系,但是我包含它们是因为我经常使用它们。

9ceoxa92

9ceoxa925#

编写了这个方便的函数,并放入了我的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
t2a7ltrp

t2a7ltrp6#

MacOS 13.2.1只运行rsync 2.6.9,但“对于rsync版本3.0.6或更高版本”方法效果很好。

wpx232ag

wpx232ag7#

如果有人找这个...我想rsync只特定的文件和文件夹,并设法做到这一点与此命令:rsync --include-from=rsync-files
对于rsync文件:

my-dir/
my-file.txt

- /*

相关问题