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

use*_*480 84 linux bash shell rsync

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

from=$1
to=$2

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

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".

您可以在手册页的"包含/排除模式规则"部分中找到一些很好的示例

  • 我在rsync版本3.0.7上试过这个,我很久以前就是从macports那里得到的,并且它不适用于这种包含/排除的顺序.这就是我最终为我工作的东西(适用于OP):`rsync -zarv --include ="*/" - include ="*.sh"--exclude ="*""$ from"" $为"`. (45认同)
  • 虽然它会为你提供所有的子目录,如果你想要rsync的子目录中有任何.sh文件,你也可能想要使用--include ="*/". (10认同)
  • 我尝试使用rsync 3.0.9但它没有用.Bijou是对的,排序不合适(首先`--include =\*.sh`然后`--exclude =\*`) (2认同)
  • 请注意,您始终可以单击编辑并建议编辑答案:) (2认同)
  • 它不适用于您的包含/排除顺序,但适用于Bijou Trouvaille建议的顺序 (2认同)
  • 为什么我们需要这么多包含,看起来像一个非常愚蠢的命令。 (2认同)
  • 我认为对命令实际执行的操作的解释将非常棒且非常有用。 (2认同)
  • `rsync` 是一个非常伟大的工具...*除了*这里的这个功能。这些“--include”和“--exclude”标志不直观且草率。 (2认同)
  • 为什么它被接受为正确答案?它还复制所有子目录,即使它们不包含目标文件 (2认同)

Wan*_*ind 43

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

rsync -zarv  --prune-empty-dirs --include "*/"  --include="*.sh" --exclude="*" "$from" "$to"
Run Code Online (Sandbox Code Playgroud)

  • 这个答案对我来说非常有效。+1 :) (2认同)
  • 这是我的要求:“如果您需要排除不包含文件的子目录并仍保留目录结构”+1 (2认同)
  • 我不明白你怎么知道 --includes 的顺序是什么? (2认同)

Ser*_*sak 13

还有一个补充:如果你只需要在一个目录中通过扩展来同步文件(没有递归),你应该使用这样的结构:

rsync -auzv --include './' --include '.ext' --exclude '*' /source/dir/ /destination/dir/
Run Code Online (Sandbox Code Playgroud)

请注意第一个中的点--include.--no-r在这种结构中不起作用.


Jim*_*ker 7

这是手册页中的重要部分:

构建要传输的文件/目录列表后,rsync会根据包含/排除模式列表依次检查要传输的每个名称,然后执行第一个匹配模式:如果是排除模式,则该文件为跳过 如果是包含模式,则不跳过该文件名;如果找不到匹配的模式,则不跳过文件名。

总结一下:

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

另外,以斜杠结尾的东西是匹配目录(就像find -type d这样)。

让我们从上面分开这个答案。

rsync -zarv  --prune-empty-dirs --include "*/"  --include="*.sh" --exclude="*" "$from" "$to"
Run Code Online (Sandbox Code Playgroud)
  1. 不要跳过任何目录
  2. 不要跳过任何.sh文件
  3. 跳过一切
  4. (示意性地,不要跳过任何内容,但是上面的规则可以防止发生默认规则。)

最后,--prune-empty-directories保持第一条规则不要在各处创建空目录。

  • _''一旦任何模式匹配,算法就会退出”_ — 这是关键,没有一个评分较高的答案能像您在这里所做的那样清楚、预先地解释它。当然,这_is_在手册页中,并且如果我仔细阅读整篇文章,我就会看到这一点。不过,谢谢。 (5认同)
  • 另一个关键概念是“当使用 --recursive (-r) 选项(由 -a 暗示)时,从左到右访问每个路径的每个子目录组件,每个目录都有机会在其内容之前排除.通过这种方式,包含/排除模式将递归地应用于每个节点的路径名”。 (2认同)