Linux rsync 仅使用包含选项复制某些类型的文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11111562/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
rsync copy over only certain types of files using include option
提问by user881480
I use the following bash script to copy only files of certain extension(in this case *.sh), however it still copies over all the files. what's wrong?
我使用以下 bash 脚本仅复制特定扩展名的文件(在本例中为 *.sh),但它仍会复制所有文件。怎么了?
from= to= rsync -zarv --include="*.sh" $from $to
采纳答案by chepner
I think --include
is used to include a subset of files that are otherwise excluded by --exclude
, rather than including only those files.
In other words: you have to think about includemeaning don't exclude.
我认为--include
用于包含由 排除的文件子集--exclude
,而不是仅包含这些文件。换句话说:您必须考虑include 的含义不要 exclude。
Try instead:
试试吧:
rsync -zarv --include "*/" --exclude="*" --include="*.sh" "$from" "$to"
For rsync version 3.0.6 or higher, the order needs to be modified as follows (see comments):
对于rsync 3.0.6或更高版本,需要修改顺序如下(见评论):
rsync -zarv --include="*/" --include="*.sh" --exclude="*" "$from" "$to"
Adding the -m
flag will avoid creating empty directory structures in the destination. Tested in version 3.1.2.
添加-m
标志将避免在目标中创建空目录结构。在 3.1.2 版本中测试。
So if we only want *.sh files we have to exclude all files --exclude="*"
, include all directories --include="*/"
and include all *.sh files --include="*.sh"
.
因此,如果我们只想要 *.sh 文件,我们必须排除所有文件--exclude="*"
,包括所有目录--include="*/"
并包括所有 *.sh 文件--include="*.sh"
。
You can find some good examples in the section Include/Exclude Pattern Rulesof the man page
你可以在手册页的包含/排除模式规则部分找到一些很好的例子
回答by Serge Roussak
One more addition: if you need to sync files by its extensions in one dir only(without of recursion) you should use a construction like this:
另外一个补充:如果您只需要在一个目录中通过扩展名同步文件(没有递归),您应该使用这样的结构:
rsync -auzv --include './' --include '*.ext' --exclude '*' /source/dir/ /destination/dir/
Pay your attention to the dot in the first --include
. --no-r
does not work in this construction.
注意第一个中的点--include
。--no-r
在这个结构中不起作用。
EDIT:
编辑:
Thanks to gbyte.co for the valuable comment!
感谢 gbyte.co 的宝贵意见!
回答by WanderingMind
The answer by @chepner will copy all the sub-directories irrespective of the fact if it contains the file or not. If you need to exclude the sub-directories that dont contain the file and still retain the directory structure, use
@chepner 的答案将复制所有子目录,而不管它是否包含文件。如果需要排除不包含该文件的子目录而仍保留目录结构,请使用
rsync -zarv --prune-empty-dirs --include "*/" --include="*.sh" --exclude="*" "$from" "$to"
回答by Jim Hunziker
Here's the important part from the man page:
这是手册页中的重要部分:
As the list of files/directories to transfer is built, rsync checks each name to be transferred against the list of include/exclude patterns in turn, and the first matching pattern is acted on: if it is an exclude pattern, then that file is skipped; if it is an include pattern then that filename is not skipped; if no matching pattern is found, then the filename is not skipped.
随着要传输的文件/目录列表的构建,rsync 依次根据包含/排除模式列表检查要传输的每个名称,并对第一个匹配模式进行操作:如果它是排除模式,则该文件是跳过;如果是包含模式,则不会跳过该文件名;如果没有找到匹配的模式,则不会跳过文件名。
To summarize:
总结一下:
- Not matching any pattern means a file will be copied!
- The algorithm quits once any pattern matches
- 不匹配任何模式意味着将复制文件!
- 一旦任何模式匹配,算法就退出
Also, something ending with a slash is matching directories (like find -type d
would).
此外,以斜杠结尾的内容是匹配目录(就像find -type d
会)。
Let's pull apart this answer from above.
让我们从上面拆开这个答案。
rsync -zarv --prune-empty-dirs --include "*/" --include="*.sh" --exclude="*" "$from" "$to"
- Don't skip any directories
- Don't skip any
.sh
files - Skip everything
- (Implicitly, don't skip anything, but the rule above prevents the default rule from ever happening.)
- 不要跳过任何目录
- 不要跳过任何
.sh
文件 - 跳过一切
- (隐含地,不要跳过任何内容,但上面的规则会阻止默认规则发生。)
Finally, the --prune-empty-directories
keeps the first rule from making empty directories all over the place.
最后,--prune-empty-directories
第一个规则是避免在所有地方创建空目录。
回答by Pascal Polleunus
If someone looks for this…
I wanted to rsync only specific files and folders and managed to do it with this command: rsync --include-from=rsync-files
如果有人在寻找这个……我只想 rsync 特定的文件和文件夹,并设法使用以下命令来做到这一点: rsync --include-from=rsync-files
With rsync-files:
使用 rsync 文件:
my-dir/
my-file.txt
- /*
回答by biocyberman
Wrote this handy function and put in my bash scripts or ~/.bash_aliases
. Tested sync'ing locally on Linux with bash and awk
installed. It works
编写了这个方便的函数并将其放入我的 bash 脚本或~/.bash_aliases
. 使用 bash 在 Linux 上本地测试同步并awk
安装。有用
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=""; 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
}
Avantages:
优势:
short handy and extensible when one wants to add more arguments (i.e. --dry-run
).
当您想要添加更多参数(即--dry-run
)时,方便且可扩展。
Example:
例子:
selrsync 'tsv,csv' ./source ./target --dry-run