Rclone 过滤与文件筛选:模式语法、include/exclude/filter 规则与应用实战
【免费下载链接】rclone"rsync for cloud storage" - Google Drive, S3, Dropbox, Backblaze B2, One Drive, Swift, Hubic, Wasabi, Google Cloud Storage, Azure Blob, Azure Files, Yandex Files项目地址: https://gitcode.com/GitHub_Trending/rc/rclone
Rclone("rsync for cloud storage")通过过滤标志(filter flags)精确控制sync、copy、move、ls、check等命令作用于哪些文件。本文以 rclone 官方文档 filtering.md 为主线,结合仓库中过滤模块的源码实现(fs/filter/filter.go、fs/filter/rules.go、fs/filter/glob.go)与测试用例,系统讲解 glob 匹配语法、正则内嵌、规则处理顺序、目录递归优化、按大小/时间/哈希分区筛选以及元数据过滤等机制。读完本文,你将能够写出准确、可复现的 include/exclude/filter 规则,安全高效地完成增量同步、选择性备份、抽查校验等任务。
过滤机制的作用范围
过滤标志决定sync、move、ls、lsl、md5sum、sha1sum、size、delete、check等命令应用于哪些路径/文件。它们以路径/文件名模式、路径列表、文件年龄、文件大小或"目录中是否存在某个文件"为条件进行筛选。对于无目录概念的基于 bucket 的远端,过滤器以类似方式作用于对象 key、年龄与大小。
三条重要的使用前提:
rclone purge不遵守过滤器——执行 purge 前务必确认目标。- 先在无损场景中验证过滤器:把过滤器应用于
rclone ls,或加--dry-run与-vv标志试运行。-vv会输出每个文件被排除时的原因(源码中通过fs.Debugf(remote, "Excluded (Path Filter)")等日志体现,见 fs/filter/filter.go)。 - 过滤器模式只能出现在过滤命令行选项里,不能写在远端路径上。例如:
rclone copy "remote:dir*.jpg" /path/to/dir—— 无过滤效果;rclone copy remote:dir /path/to/dir --include "*.jpg"—— 有效。
重要提醒:避免在一条 rclone 命令中混用--include...、--exclude...或--filter...中的任意两类标志,结果可能不符合预期;应改用--filter...标志显式编排顺序。
匹配路径/文件名的模式语法
Rclone 的匹配规则采用 glob 风格,下面是完整的形式化定义(示例见后文表格)。
* 匹配任意一串非分隔符(/)字符 ** 匹配任意一串字符,包括 / 分隔符 ? 匹配任意单个非分隔符(/)字符 [ [ ! ] { character-range } ] 字符类(必须非空) { pattern-list } 模式备选列表 {{ regexp }} 用于匹配的正则表达式 c 匹配字符 c(c 不为 *, **, ?, \, [, {, }) \c 匹配保留字符 c(c = *, **, ?, \, [, {, })或转义字符类中的字符其中:
- character-range(字符范围):
c匹配普通字符 c(c 不为\、-、]);\c匹配保留字符 c(c =\、-、]);lo - hi匹配范围内任意字符(lo <= c <= hi),例如[a-z]。 - pattern-list(模式列表):
pattern { , pattern },即以逗号分隔(不含空格)的若干模式,如*.{jpg,png}。 - 字符类支持 Go 正则语法中的三类便捷写法:
- 命名类:
[\d]、[^\d]、[\D]、[^\D]; - Perl 风格类:
\s、\S、\w、\W; - ASCII 类:
[[:alnum:]]、[[:alpha:]]、[[:punct:]]、[[:xdigit:]]等。
- 命名类:
- regexp:面向高级用户的完整正则表达式,要求是任何不包含
}}的 RE2 正则(详见下一节)。
锚定语义:以/开头与不以/开头
- 模式以
/开头时,只匹配目录树顶层——相对远端根目录而言(注意不一定是磁盘/云盘的根)。 - 模式不以
/开头时,从路径/文件名的末尾开始匹配,但必须匹配一个完整的路径元素——即必须从某个/分隔符或路径起点开始。
以file.jpg为例:
file.jpg - 匹配 "file.jpg" - 匹配 "directory/file.jpg" - 不匹配 "afile.jpg" - 不匹配 "directory/afile.jpg" /file.jpg - 匹配远端根目录下的 "file.jpg" - 不匹配 "afile.jpg" - 不匹配 "directory/file.jpg"顶层是相对命令中的源/目的目录
"顶层"未必是驱动的顶层。例如在 Windows 本地目录结构中:
F: ├── bkp ├── data │ ├── excl │ │ ├── 123.jpg │ │ └── 456.jpg │ ├── incl │ │ └── document.pdf要把data目录内容复制进bkp、同时排除子目录excl的内容,下面的命令把F:\data与F:\bkp当作过滤的顶层:
rclone copy F:\data\ F:\bkp\ --exclude=/excl/**重要:即使运行在 Microsoft Windows 上,路径/文件模式中也必须使用/而非\。
大小写敏感与--ignore-case
简单模式默认区分大小写,除非使用--ignore-case标志:
默认(无 --ignore-case) potato - 匹配 "potato" - 不匹配 "POTATO" 加 --ignore-case potato - 匹配 "potato" - 匹配 "POTATO"在过滤模式中使用正则表达式
glob 风格简单易用,但无法做到绝对精确的控制。为此 rclone 为高级用户提供正则语法:将正则表达式用{{与}}包裹即可(任意不含}}的 Go/RE2 风格正则,语法由 Go regexp 包定义)。当 glob 不以/开头时正则只匹配最后一段路径;以/开头时匹配整个路径名。其转换为完整正则的规则如下:
{{regexp}} 变为 (^|/)(regexp)$ /{{regexp}} 变为 ^(regexp)$两点需要特别注意:
- rclone 不解析你提供的正则内容。只要存在任何正则过滤模式,rclone 就无法使用目录过滤规则做递归剪枝,因为必须逐路径与正则比对。
- 小心通配符吞掉路径分隔符。要匹配以
start开头、以end结尾的文件名,应写{{start[^/]*end\.jpg}},而不是{{start.*end\.jpg}}——后者中.*会匹配/,从而错误地命中"目录start下名为end.jpg的文件"。
正则可与 glob 混用,例如*.{{jpe?g}}能匹配file.jpg、file.jpeg但不匹配file.png。也可以用内联标志控制大小写,例如*.{{(?i)jpg}}匹配file.jpg与file.JPG,但不匹配file.png。
调试技巧:执行命令时加-vv --dump filters可查看过滤模式被转换成的正则形式——rclone 本质上是把 glob 模式编译为正则来实现匹配(核心转换函数为GlobPathToRegexp,见 fs/filter/glob.go)。
模式示例速查表
| 描述 | 模式 | 匹配 | 不匹配 |
|---|---|---|---|
| 通配符 | *.jpg | /file.jpg、/dir/file.jpg | /file.png、/dir/file.png |
| 根锚定 | /*.jpg | /file.jpg、/file2.jpg | /file.png、/dir/file.jpg |
| 备选列表 | *.{jpg,png} | /file.jpg、/dir/file.png | /file.gif、/dir/file.gif |
| 路径通配 | dir/** | /dir/anyfile、/subdir/dir/subsubdir/anyfile | file.png、/subdir/file.png |
| 单字符 | *.t?t | /file.txt、/dir/file.tzt | /file.qxt、/dir/file.png |
| 范围 | *.[a-z] | /file.a、/dir/file.b | /file.0、/dir/file.1 |
| 转义 | *.\?\?\? | /file.???、/dir/file.??? | /file.abc、/dir/file.def |
| 字符类 | *.\d\d\d | /file.012、/dir/file.345 | /file.abc、/dir/file.def |
| 正则 | *.{{jpe?g}} | /file.jpeg、/dir/file.jpg | /file.png、/dir/file.jpeeg |
| 根锚定正则 | /{{.*\.jpe?g}} | /file.jpeg、/file.jpg | /file.png、/dir/file.jpg |
过滤规则如何作用于文件
路径/文件名过滤器由以下标志之一或多个构成:--include、--include-from、--exclude、--exclude-from、--filter、--filter-from。同一标志可多次出现。
规则的处理顺序
rclone 内部把 include/exclude 规则合并成一条规则列表,规则的处理顺序会影响结果。同类型的所有标志按上述顺序统一处理(与命令行上各类标志的出现顺序无关),其处理次序从源码 fs/filter/rules.go 的parseRules可以清晰印证:
1. --include (每条模式单独加入) 2. --include-from (按文件自上而下逐行加入) 3. --exclude (每条模式单独加入) 4. --exclude-from (按文件自上而下逐行加入) 5. --filter (按 +/- 前缀处理) 6. --filter-from (按文件自上而下处理)同一标志的多个实例则按其命令行位置从左到右处理。想要自由混排 include/exclude 的先后顺序,只能用--filter...标志。
源码parseRules还在两个位置做了增强:
- 当同时出现 include 类与 exclude 类标志时,会输出警告 "Using --filter is recommended instead of both --include and --exclude as the order they are parsed in is indeterminate"(fs/filter/rules.go),进一步印证混用的不确定性。
- 只要存在
--include或--include-from,就会在内部规则列表末尾隐含追加一条排除规则/ **(add(false, "/**"),见 fs/filter/rules.go)。--filter + ...形式则不触发该隐含规则。
首匹配即决定
每个经过的路径/文件名都按合并后的规则列表顺序匹配,命中的第一条规则即决定包含或排除,其后规则不再评估。若遍历完所有规则(含隐含规则)仍无匹配,则默认包含该文件(fs/filter/rules.go 中include方法:遍历规则命中即返回rule.Include,否则返回true)。被包含的路径随后交给 rclone 命令处理。
查看内部规则列表
想查看命令的内部合并规则列表(正则形式),加--dump filters标志即可。配合-vv,输出会列出内部过滤元素并展示它们如何作用于每个源路径/文件(实现见 fs/filter/filter.go 的DumpFilters)。目前 rclone 没有提供把正则形式的过滤选项直接传入命令行的手段,不过字符类过滤规则本身已内含字符类语法。
目录过滤规则与目录递归优化
rclone 命令作用于路径/文件名而非目录本身;整目录内容可用directory/*或递归的directory/**匹配。以结尾/分隔符定义的规则即为目录过滤规则,例如/directory/subdirectory/。
命令可根据目录过滤规则决定是否递归进入子目录,从而避免列出无关目录、优化远端访问。是否值得优化取决于具体规则与源远端内容。
什么情况下会做目录递归优化
当满足以下任一条件时,rclone 会进行目录递归优化:
- 源远端不支持
ListR原语(本地盘、sftp、Microsoft OneDrive、WebDAV 不支持;Google Drive 与大多数 bucket 存储支持,Feature 定义见 fs/features.go); - 在其他支持
ListR的远端上,命令本身不是天然递归的,且未使用--fast-list。ls、lsf -R、size是天然递归的,而sync、copy、move不是; - 命令应用了
--disable ListR标志。
rclone 会从路径/文件过滤规则隐含推导目录过滤规则(例如 include 规则/a/*.jpg会推导出目录 include 规则/a/),可用--dump filters查看推导结果。源码层面,Filter.Add对文件规则调用addDirGlobs把 glob 转成目录 glob 并加入目录规则集(fs/filter/filter.go)。
注意:只要使用了正则过滤模式,就无法做目录递归优化,rclone 必须把每条路径与正则比对。
目录规则限定了范围但不算文件匹配
目录过滤规则可以限制命令的作用域,但仍需提供路径/文件过滤器才能匹配文件。例如:
rclone ls remote: --include /directory/不会匹配任何文件:因为是--include选项,隐含的- **排除规则生效;/directory/模式只起到"忽略该目录之外的一切、优化远端访问"的作用。
再看一个组合示例,rclone ls remote: --filter-from filter-list.txt,其中filter-list.txt内容:
- /dir1/ - /dir2/ + *.pdf - **效果:dir1、dir2及其所有子目录中的文件被完全排除;只有远端根或子目录下后缀为pdf的文件被列出;末尾的- **防止未被上述规则命中的路径/文件进入列表。这正是文档建议的"最严格规则放前面、逐级放宽、最后兜底排除"的编排方式。
目录规则的边界:pattern-list 与空目录
使用 pattern-list 语法时,若其中任一模式项包含/或**,rclone 无法从中推导目录过滤规则。例如 include 规则:
{dir1/**,dir2/**}能匹配dir1、dir2之下的文件,但无法用该规则把无关目录dir3排除在遍历之外。
这种差异通常只影响性能、不影响结果,但有一个例外:使用--create-empty-src-dirs的sync操作会创建所有被遍历到的空目录。上述{dir1/**,dir2/**}会在源端存在dir3时,把空目录dir3也创建到目标端。把过滤器改为{dir1,dir2}/**,或拆成两条 include 规则--include dir1/** --include dir2/**,则匹配相同文件的同时还能过滤目录,空目录dir3就不会再被创建。
另外,--exclude-if-present会基于"目录内是否存在指定文件"创建目录排除规则,且优先级高于其他目录过滤规则(其底层实现DirContainsExcludeFile会在遍历时逐个目录探测标记文件是否存在,见 fs/filter/filter.go)。
六个过滤标志逐个详解
--exclude:按模式排除文件
按单条排除规则把路径/文件排除出命令范围。可重复。排除以"dir/"结尾的规则会被等价扩展为"dir/**"(源码 fs/filter/filter.go 明确把排除dir/与排除dir/**等同)。不应用于--include、--include-from、--filter、--filter-from混用;与--files-from、--files-from-raw、--files-from0同时使用时无效。
rclone ls remote: --exclude *.bak # 排除所有 .bak rclone size remote: --exclude "/dir/**" # 排除根目录 dir 及其子目录,统计其余文件总大小Windows 下排除名字中含[JP]、[KR]、[HK]的文件:
rclone ls remote: --exclude "*\[{JP,KR,HK}\]*"双引号防止 shell 解释\;\转义[、]使其按字面处理而非字符范围;{JP,KR,HK}构成 pattern-list。其他操作系统需用单引号:rclone ls remote: --exclude '*\[{JP,KR,HK}\]*'。
--exclude-from:从文件读取排除规则
从命名文件读取若干排除规则。文件可含注释与规则行。例如exclude-file.txt:
# a sample exclude rule file *.bak file2.jpgrclone ls remote: --exclude-from exclude-file.txt等价于rclone ls remote: --exclude file2.jpg --exclude "*.bak"。适合规则较多时使用;可重复。--exclude-from -从标准输入读取规则。与--files-from系列同时使用时无效。
--include:按模式包含文件
按单条 include 规则把路径/文件加入命令范围。可重复。--include会在内部过滤列表末尾隐含- **规则,因此若与 exclude/filter 类标志混用,必须在 include 中写全所有希望保留的文件规则——更灵活的选择是用--filter-from。
rclone ls remote: --include "*.{png,jpg}"只列出后缀为.png、.jpg的文件,其余全部排除。再如多条 copy 命令的合并:
rclone copy /vol1/A remote:A rclone copy /vol1/B remote:B等价于:
rclone copy /vol1 remote: --include "{A,B}/**"利用 ASCII 字符类:rclone ls remote:/wheat --include "??[^[:punct:]]*"列出remote:中wheat目录(含子目录)内第三个字符不是标点的文件。
--include-from:从文件读取包含规则
include-file.txt示例:
# a sample include rule file *.jpg file2.avirclone ls remote: --include-from include-file.txt等价于rclone ls remote: --include file2.avi --include "*.jpg"。同样隐含- **排除规则;可重复;--include-from -从标准输入读取。
--filter:添加单条+/-过滤规则
以单条 include/exclude 规则的形式指定文件,+前缀表示包含、-前缀表示排除。--filter +与--include不同:--include会在内部规则列表末尾隐含- **,而--filter + ...不会隐含该规则(这正是parseRules仅对IncludeRule/IncludeFrom追加/**的原因)。可重复;不与 include/exclude 类标志混用;与--files-from系列共用时无效。
rclone ls remote: --filter "- *.bak" # 排除所有 .bak 文件--filter-from:从文件读取过滤规则
规则文件以+开头为包含规则、-开头为排除规则,!清空此前全部规则,按文件中自上而下的顺序处理。建议最严格规则放最前,逐步放宽。
- 以
#或;开头的行是注释并被忽略; - 不支持行内注释——行尾内容会作为模式一部分参与匹配;
- 可重复,
--filter-from -读标准输入。
综合示例filter-file.txt:
# a sample filter rule file - secret*.jpg + *.jpg + *.png + file2.avi - /dir/tmp/** # WARNING! This text will be treated as part of the path. - /dir/Trash/** + /dir/** # exclude everything else - *rclone ls remote: --filter-from filter-file.txt效果:包含所有jpg、png及file2.avi;排除匹配secret*.jpg者;包含远端根下dir目录的全部内容(remote:dir/Trash除外);其余全部排除。注意/dir/tmp/**行——注释写在行尾会被当作路径的一部分,这正是文档警告的行内注释陷阱。
再看只用到全局文件的示例:
- secret*.jpg + *.jpg + *.png + file2.avi - *file1.jpg、file3.png、file2.avi会被列出,secret17.jpg及无.jpg/.png后缀的文件被排除。
演示!清空语义的示例:
+ *.jpg + *.gif ! + 42.doc - *由于!清空了前面的*.jpg、*.gif规则,最终只列出42.doc。
源码中addRule精确实现了这三种前缀:!调用clear()清空规则集,-调用add(false, ...),+调用add(true, ...),其余格式返回 "malformed rule" 错误(fs/filter/rules.go)。
按文件列表精确选择:--files-from系列
--files-from、--files-from-raw、--files-from0会覆盖并取代其他过滤选项,无法与--include、--exclude、--filter等混用。源码在NewFilter中对此有硬性校验:只要存在任何其他激活的过滤器却仍使用--files-from,会直接报错 "the usage of --files-from overrides all other filters"(fs/filter/filter.go)。三者彼此之间可同时使用。
--files-from
从命名文件读入路径/文件列表,rclone 按列表顺序处理且只处理这些文件。逐行处理细节:
- 去除行首尾空白;
#、;开头的行被忽略(由forEachLine实现,fs/filter/rules.go); --files-from -从标准输入读列表;- 结合
--no-traverse时不遍历远端,而是按列表逐条直接寻址(每条通常 1 次 API 调用),适合短列表 + 巨量文件的场景; - 列表中的名字在源端不存在时不报错;
- 标志可重复,多个文件从左到右读取;
- 文件内路径以命令指定的 root 为基准,行首
/被忽略。
示例files-from.txt:
# comment file1.jpg subdir/file2.jpgrclone copy --files-from files-from.txt /home/me/pics remote:pics仅当下列文件存在时复制它们:
/home/me/pics/file1.jpg → remote:pics/file1.jpg /home/me/pics/subdir/file2.jpg → remote:pics/subdir/file2.jpg若文件引用了绝对路径(如/home/user1/42、/home/user1/dir/ford、/home/user2/prefect),先找公共子目录(此处为/home),列表写相对余下路径:
user1/42 user1/dir/ford user2/prefectrclone copy --files-from files-from.txt /home remote:backup三个文件分别映射到remote:backup/user1/42、remote:backup/user1/dir/ford、remote:backup/user2/prefect。若以/为 root,则列表直接写绝对路径、命令变为rclone copy --files-from files-from.txt / remote:backup,远端会多出home目录层级。
--files-from-raw
与--files-from相同,但输入按原始方式读取:行首尾空白不做去除,;、#开头的行不跳过。rclone lsf的输出格式与它兼容,可直接导出远端文件列表再喂给--files-from-raw(相关命令见 rclone lsf 命令文档)。
--files-from0
与--files-from-raw相同,但输入以NUL(\0)而非换行符分隔,从而支持文件名内含换行符的场景。其语义类似find的-print0与xargs的-0;源码使用定制的scanNulScanner 切分函数实现(fs/filter/rules.go)。
find /path -print0 | rclone copy --files-from0 - / remote:pathShell 元字符的引号处理
含 shell 元字符的过滤模式可能被 shell 先行展开而导致命令不符合预期,需按平台引号处理:
- Linux、macOS(以
*为例):--include \*.jpg、--include '*.jpg'或--include='*.jpg'; - Windows 的扩展由命令本身而非 shell 完成,
--include *.jpg无需引号。
如果遇到错误Command .... needs .... arguments maximum: you provided .... non flag arguments:,常见原因是远端名或标志值中含有空格,解决办法是对含空格的值加引号。
按文件大小与年龄过滤
大小与年龄过滤属于"其他过滤器",同样作用于命令范围内的文件。它们的默认值与取值范围在 fs/filter/filter.go 的选项定义与Opt默认值中给出:--min-size/--max-size默认-1(即关闭),--min-age/--max-age默认fs.DurationOff。
--min-size/--max-size
- 控制命令范围内文件的最小/最大体积。默认单位
KiB,也接受后缀B、K、M、G、T、P。 - 例:
rclone ls remote: --min-size 50k列出 50 KiB 及以上文件;rclone ls remote: --max-size 1G列出 1 GiB 及以下文件。 - 相关尺寸单位说明可查阅 docs.md 尺寸选项部分。
rclone ls remote: --min-size 50k rclone ls remote: --max-size 1G--max-age/--min-age
--max-age控制最大文件年龄(只对文件生效,不作用于目录)。例:rclone ls remote: --max-age 2d列出 2 天以内(含)的文件。--min-age控制最小文件年龄(同样只对文件生效)。例:rclone ls remote: --min-age 2d列出 2 天及以上的文件。- 合法时间格式与 docs.md 时间选项部分 说明一致。
源码将其换算为修改时间窗口:--min-age设置时间上界ModTimeTo(早于此才算"足够老"),--max-age设置时间下界ModTimeFrom,逐对象在Include中做比较(fs/filter/filter.go 与 fs/filter/filter.go)。若--min-age大于--max-age,构造过滤器时会直接返回错误filter: --min-age ... can't be larger than --max-age ...。
--hash-filter:确定性分区选择文件子集
--hash-filter提供确定性地选择文件子集的能力,适用场景包括:
- 在多台机器上分担大型 sync 任务;
- 抽查一部分文件是否发生 bitrot;
- 其他需要抽样文件的场景。
语法
--hash-filter K/NN:分区总数(必须是正整数);K:要选取的具体分区(0到N的整数)。
例如--hash-filter 1/3选取全部文件的第一个三分之一;--hash-filter 2/3与--hash-filter 3/3分别选取第二、第三个分区。各分区互不重叠,合起来覆盖全部文件、无重复。
随机选区分区:把K写成@,如--hash-filter @/3会在 0..2 之间随机选一个数,且该选择在多次重试间保持不变(源码中k = rand.Uint64N(n)一次性确定并存入Filter,见 fs/filter/filter.go)。
工作原理
源码IncludeRemote(fs/filter/filter.go)揭示了其实现链条:
- 取每个文件的完整路径;
- 先做 Unicode NFC 规范化、再转小写(保证大小写不敏感或需 Unicode 规范化的远端归一后落入同一分区);
- 对规范化路径取 MD5 摘要并读取为 64 位整数;
- 对该哈希值做
mod N,得到分区号; - 分区号不等于
K则排除;否则继续应用其他过滤器(若有)。
其中K在解析时即做k %= n,因此--hash-filter 4/4与--hash-filter 0/4等价。重要:应用该过滤器需要遍历所有目录。
使用注意
- 可安全用于
rclone sync:源与目标的选择结果一致(因为是对路径本身哈希); - 不要与
--delete-excluded共用,可能误删未选中的文件; - 使用
--files-from、--files-from-raw、--files-from0时被忽略(IncludeRemote中filesFrom优先级更高)。
示例
当前目录含file1.jpg至file9.jpg,按 4 分区划分:
$ rclone lsf --hash-filter 0/4 . file1.jpg file5.jpg $ rclone lsf --hash-filter 1/4 . file3.jpg file6.jpg file9.jpg $ rclone lsf --hash-filter 2/4 . file2.jpg file4.jpg $ rclone lsf --hash-filter 3/4 . file7.jpg file8.jpg $ rclone lsf --hash-filter 4/4 . # 与 --hash-filter 0/4 相同 file1.jpg file5.jpg同步前四分之一文件:
rclone sync --hash-filter 1/4 source:path destination:path随机抽查 1% 文件做完整性校验:
rclone check --download --hash-filter @/100 source:path destination:path其他相关标志
--delete-excluded:同步时删除目标端被排除文件
重要:此标志对数据有危险——请先配合--dry-run与-v试运行。与rclone sync联用时,--delete-excluded会删除目标端所有被排除在本次命令范围之外的文件。例如:
rclone --min-size 50k --delete-excluded sync A: B:B:上所有小于 50 KiB 的文件都会因不在 sync 范围而被删除(delete_excluded默认关闭,见 fs/filter/filter.go)。相关同步语义可参考 rclone sync 命令文档。
--dump filters:输出过滤器便于调试
把当前定义的过滤器以正则形式输出到标准输出,配合-vv可查看每个文件被过滤的情况,是排查过滤规则的首选调试手段。用法:rclone --dump filters ls remote:。
--exclude-if-present:依据标记文件排除目录
--exclude-if-present依据目录内是否存在指定文件来决定该目录是否处于命令范围内;标志可重复以检查多个文件名,命中任意一个即排除整个目录。该标志优先级高于其他过滤标志。
给定目录结构:
dir1/file1 dir1/dir2/file2 dir1/dir2/dir3/file3 dir1/dir2/dir3/.ignorerclone ls --exclude-if-present .ignore dir1由于dir3内含.ignore,dir3、file3、.ignore均不会被列出。遍历中IncludeDirectory会先调用DirContainsExcludeFile探测各目录内标记文件(fs/filter/filter.go),命中即不再递归该目录。
元数据过滤
元数据过滤器与文件名过滤的工作方式高度相似,区别在于匹配对象是对象上的元数据,而非名称。元数据以key=value模式表示,键值两边均可套用普通过滤模式或正则。与文件名过滤一样,元数据过滤只作用于文件、不作用于目录。
例如仅列出本地 mode 为100664的文件:
rclone lsf -M --files-only --metadata-include "mode=100664" .又如只显示atime、mtime或btime落在某日期(2022-12-16)的文件:
rclone lsf -M --files-only --metadata-include "[abm]time=2022-12-16*" .可用的标志(每个均可重复,语义与文件名过滤标志一一对应):
--metadata-include/--metadata-include-from(-表示读标准输入)--metadata-exclude/--metadata-exclude-from(-表示读标准输入)--metadata-filter/--metadata-filter-from(-表示读标准输入)
处理方式与文件过滤规则的应用完全一致,只是以元数据模式替代文件名模式。源码在Include中把对象的键值元数据拼成key=value字符串集后再走规则匹配(fs/filter/filter.go);无元数据时插入空键值项,使规则的默认行为(未匹配则包含)得以保持。相关选项同时归于Filter与Metadata两个分组,见 fs/filter/filter.go。元数据机制的总体说明见 docs.md 元数据部分。
常见陷阱与排查建议
rclone 支持论坛上最高频的过滤问题集中在三点(文档结论):
- 未使用相对远端根目录的路径——
--files-from与目录规则中的路径都相对命令指定的 root 解析; - 未用
/表示从远端根匹配——不带/的模式从路径尾部做整段匹配,容易误判层级; - 未用
**匹配目录内容——directory/*只匹配其直接子项,递归内容需directory/**。
建议的排查路线:先rclone ls <remote> --filter ...无风险验证,再用-vv --dump filters观察规则被编译成的正则与逐文件匹配日志,确认命中预期后再应用于sync/delete等写操作。结合源码可进一步确证行为:规则编译与去重位于 fs/filter/rules.go 的rules.add,glob→正则的转换位于 fs/filter/glob.go,命令行标志到过滤器的装配由 fs/filter/filterflags/filterflags.go 的AddFlags完成,而全面的行为断言可参考 fs/filter/filter_test.go 与 fs/filter/glob_test.go 中的测试用例。
【免费下载链接】rclone"rsync for cloud storage" - Google Drive, S3, Dropbox, Backblaze B2, One Drive, Swift, Hubic, Wasabi, Google Cloud Storage, Azure Blob, Azure Files, Yandex Files项目地址: https://gitcode.com/GitHub_Trending/rc/rclone
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考