ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

rclone 文件名转换体系:lib/transform 包与 --name-transform 选项全解析

rclone 文件名转换体系:lib/transform 包与 --name-transform 选项全解析 rclone 文件名转换体系lib/transform 包与 --name-transform 选项全解析【免费下载链接】rclonersync 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 仓库中由go generate自动生成的 lib/transform/transform.md 为核心系统讲解--name-transform选项的全部转换模式、字符映射表与编码掩码并结合 lib/transform/transform.go、lib/transform/options.go 等源码剖析其逐段解析、校验与调用的底层机制。读完后你既能直接使用rclone convmv、sync、copy、move完成批量重命名与前缀/后缀/正则/Base64/编码类改名也能从源码层面理解每一次转换是如何被安全地施加到路径上的。1. 这套机制解决什么问题lib/transform包提供了一组“路径名转换”函数包注释见 transform.go由rclone的多个命令共享convmv就地批量转换文件和目录名是该机制最典型的入口命令签名为rclone convmv dest:path --name-transform XXX且必须显式指定--name-transform否则直接报错见 convmv.go 中对transform.Transforming的检查。该命令自 v1.70 起提供。sync / copy / move--name-transform在这些传输命令中同样可用。从源码调用链看目录遍历阶段在 fs/march/march.go 对每个条目调用transform.Path同步阶段在 fs/sync/sync.go 对目录元数据路径进行转换并用fs.NewOverrideDirectory覆盖源目录名复制阶段在 fs/operations/copy.go 对远程路径再次转换。选项本身通过全局配置项注入fs/config.go 中定义了NameTransform []stringconfig key 为name_transform即每个--name-transform都是独立的一条转换规则可重复传入并按命令行给出的顺序依次应用。2. 转换选项速查表完整继承自原文档下表即 transform.md 中给出的命令与描述覆盖全部已实现的转换算法选项作用--name-transform prefixXXXX在文件名前加前缀 XXXX--name-transform suffixXXXX在文件名后扩展名之后加后缀 XXXX--name-transform suffix_keep_extensionXXXX加后缀但保留原扩展名file.txt变为file_XXXX.txt--name-transform trimprefixXXXX若文件名以 XXXX 开头则去掉--name-transform trimsuffixXXXX若文件名以 XXXX 结尾则去掉--name-transform regexpattern/replacement应用正则替换Go/Perl 风格--name-transform replaceold:new把文件名中的 old 全部替换为 new--name-transform date{YYYYMMDD}追加或前缀一个日期格式串--name-transform truncateN截断文件名至最多 N 个字符--name-transform truncate_keep_extensionN截断至 N 字符但保留扩展名--name-transform truncate_bytesN截断至最多 N 字节非字符数--name-transform truncate_bytes_keep_extensionN按字节截断并保留扩展名--name-transform base64encode将文件名做 Base64 编码--name-transform base64decode将 Base64 文件名解码还原--name-transform encoderENCODING按编码掩码转换如 ISO-8859-1、Windows-1252、Macintosh--name-transform decoderENCODING按编码掩码反向解码--name-transform charmapMAP应用字符集映射转换--name-transform lowercase文件名转小写--name-transform uppercase文件名转大写--name-transform titlecase文件名转 Title Case--name-transform ascii去掉非 ASCII 字符--name-transform url对文件名做 URL 编码--name-transform nfc/nfd/nfkc/nfkd转换为对应的 Unicode 规范化形式--name-transform command/path/to/my/program执行外部程序来转换文件名几个源码层面的实现细节值得注意均出自 transform.go 的transformPathSegmentsuffix与suffix_keep_extension的区别suffix是直接拼接在完整文件名后suffix_keep_extension会先把扩展名拆出见SuffixKeepExtensiontransform.go把后缀插在扩展名之前。扩展名拆分函数splitExtension还会查mime表识别.tar.gz这类多段扩展名。base64encode使用的是 URL 安全变体base64.URLEncoding注释明确说明是为了避免产生/这种路径分隔字符transform.go。base64decode对.DS_Store做了白名单跳过避免误伤transform.go。ascii是纯删除toASCII把所有大于 127 的 rune 直接丢弃cmap.go所以The Quick Brown Fox!.txt会变成带空格的The Quick Brown Fox!.txt。regex用regexp.MustCompile编译模式替换串支持$1、${name}等捕获组语法replace则是简单的strings.ReplaceAlltransform.go。command是真正的外部进程调用mapper用exec.Command(command, s)把当前路径段作为参数传给外部程序并取其CombinedOutput去掉首尾空白作为结果transform.go。示例中all,commandecho即原样输出。从源码结构看算法枚举 options.go 中还声明了ConvIndexindex模式但transformPathSegment的switch未实现该分支会落入 default 返回 this option is not yet implemented因此当前版本实际不可用。3. 三种作用域标签file / dir / all每条规则可带一个作用域标签决定转换施加在路径的哪一部分常量定义见 options.go解析逻辑见parseTagoptions.go标签效果file只转换文件的“叶子”文件名默认省略标签时即是dir只转换目录名目录可出现在路径任意层级all对文件与目录的整条路径全部转换用法示例--name-transform file,prefixABC、--name-transform dir,prefixDEF。对nfc这类 Unicode 规范化转换通常应使用all因为目录名同样可能含组合字符。file/dir标签对文件的实际效果由 transform_test.go 精确刻画file,prefix1作用于a/b/c.txt→a/b/1c.txt只动叶子dir,prefix1作用于a/b/c.txt→1a/1b/c.txt叶子不动各级目录都动all,prefix1作用于a/b/c.txt→1a/1b/1c.txtfile,prefix1对目录本身isDirtrue不做任何事a/b保持a/b。4. 转换模式的完整清单transform.md 中列出的全部 Conversion modes 如下与 options.go 的Choices()一一对应none nfc nfd nfkc nfkd replace prefix suffix suffix_keep_extension trimprefix trimsuffix index date truncate truncate_keep_extension truncate_bytes truncate_bytes_keep_extension base64encode base64decode encoder decoder ISO-8859-1 Windows-1252 Macintosh charmap lowercase uppercase titlecase ascii url regex command其中requiresValueoptions.go列出了必须带值的模式replace、prefix、suffix、suffix_keep_extension、trimprefix、trimsuffix、index、date、四个truncate*、encoder、decoder、regex、command其余如uppercase、base64encode、nfc等可直接使用。4.1 date 模式的日期格式占位符date模式通过AppyTimeGlobstransform.go把{...}中的格式名替换为当前本地时间的格式化结果TimeFormattransform.go支持的格式名包括 Go 标准库全部命名常量Layout、ANSIC、RFC3339、Stamp、DateOnly等以及两个实用别名{YYYYMMDD}→20060102{macfriendlytime}兼容MacFriendlyTime/mac→2006-01-02 0304PM注释说明之所以如此是因为 macOS 文件名不允许冒号。占位符支持出现在值中任意位置例如date-{YYYYMMDD}会把日期追加为-20260731形式测试用例见 transform_test.go。4.2 字符映射表Char mapscharmapMAP支持 transform.md 中列出的 40 余种字符集包括IBM-Code-Page-037 / 437 / 850 / 852 / 855 / 860 / 862 / 863 / 865 / 866 / 1047 / 1140 Windows-Code-Page-858 ISO-8859-1 ~ 16缺 11、12 KOI8-R、KOI8-U Macintosh、Macintosh-Cyrillic Windows-874、Windows-1250 ~ 1258 X-User-Defined这份清单不是手写的而是 cmap.go 遍历golang.org/x/text的charmap.All动态生成的。转换行为由encodeWithReplacementcmap.go决定目标字符集中无法表示的 rune 会统一替换为下划线_——这正是示例中变成_、Café变成Caf_的原因。4.3 编码掩码Encoding masksencoder/decoder与charmap不同它们走的是 rclone 自己的编码器体系encoder.MultiEncoder按“掩码”逐类处理特殊字符。可选掩码完整清单继承自 transform.mdAsterisk、BackQuote、BackSlash、Colon、CrLf、Ctl、Del、Dollar、Dot、 DoubleQuote、Exclamation、Hash、InvalidUtf8、LeftCrLfHtVt、LeftPeriod、 LeftSpace、LeftTilde、LtGt、None、Percent、Pipe、Question、Raw、 RightCrLfHtVt、RightPeriod、RightSpace、Semicolon、SingleQuote、Slash、SquareBracket掩码可以组合如encoderColon,SquareBracket会把:换成全角、[ ]换成 用于规避 Windows/macOS 等文件系统的非法字符。5. 官方示例逐条精讲完整继承自原文档以下示例全部来自 transform.md与 transform_test.go 中TestVarious的断言完全一致可直接复制运行convmv场景下路径为远端路径--dry-run可先预览rclone convmv stories/The Quick Brown Fox!.txt --name-transform all,uppercase // Output: STORIES/THE QUICK BROWN FOX!.TXTrclone convmv stories/The Quick Brown Fox!.txt --name-transform all,replaceFox:Turtle --name-transform all,replaceQuick:Slow // Output: stories/The Slow Brown Turtle!.txtrclone convmv stories/The Quick Brown Fox!.txt --name-transform all,base64encode // Output: c3Rvcmllcw/VGhlIFF1aWNrIEJyb3duIEZveCEudHh0rclone convmv c3Rvcmllcw/VGhlIFF1aWNrIEJyb3duIEZveCEudHh0 --name-transform all,base64decode // Output: stories/The Quick Brown Fox!.txtrclone convmv stories/The Quick Brown Fox Went to the Café!.txt --name-transform all,nfc // Output: stories/The Quick Brown Fox Went to the Café!.txtrclone convmv stories/The Quick Brown Fox Went to the Café!.txt --name-transform all,nfd // Output: stories/The Quick Brown Fox Went to the Café!.txtrclone convmv stories/The Quick Brown Fox!.txt --name-transform all,ascii // Output: stories/The Quick Brown Fox!.txtrclone convmv stories/The Quick Brown Fox!.txt --name-transform all,trimsuffix.txt // Output: stories/The Quick Brown Fox!rclone convmv stories/The Quick Brown Fox!.txt --name-transform all,prefixOLD_ // Output: OLD_stories/OLD_The Quick Brown Fox!.txtrclone convmv stories/The Quick Brown Fox Went to the Café!.txt --name-transform all,charmapISO-8859-7 // Output: stories/The Quick Brown _ Fox Went to the Caf_!.txtrclone convmv stories/The Quick Brown Fox: A Memoir [draft].txt --name-transform all,encoderColon,SquareBracket // Output: stories/The Quick Brown Fox A Memoir draft.txtrclone convmv stories/The Quick Brown Fox Went to the Café!.txt --name-transform all,truncate21 // Output: stories/The Quick Brown Foxrclone convmv stories/The Quick Brown Fox!.txt --name-transform all,commandecho // Output: stories/The Quick Brown Fox!.txtrclone convmv stories/The Quick Brown Fox! --name-transform date-{YYYYMMDD} // Output: stories/The Quick Brown Fox!-20260731rclone convmv stories/The Quick Brown Fox! --name-transform date-{macfriendlytime} // Output: stories/The Quick Brown Fox!-2026-07-31 0455PMrclone convmv stories/The Quick Brown Fox!.txt --name-transform all,regex[\\.\\w]/ab // Output: ababababababab/ababab ababababab ababababab ababab!abababab几点解读url模式在测试中的结果为stories/TheQuickBrown%F0%9F%A6%8AFox%21.txttransform_test.go即url.QueryEscape的输出形态空格变、非 ASCII 变百分号编码。truncate系列在 transform_test.go 里有一组针对俄语长文件名的边界用例truncate按 UTF-8 字符数计truncate_bytes按字节计_keep_extension变体在“扩展名长度已超过截断上限”时不做任何修改如photo.jpeg配truncate_keep_extension3保持原样对应truncateChars中keep 0的报错分支transform.go。truncateBytes还会回退缩进避免把一个多字节 UTF-8 字符拦腰截断transform.go。6. 源码纵深一条规则是如何执行的6.1 解析字符串到 transform 结构每个--name-transform字符串由parseoptions.go拆解为transform{key, value, tag}三元组先剥离file,/dir,/all,前缀再按第一个切分 key 与 valuevalue 中允许再出现之外的字符但整条规则只允许恰好一个否则报 too many values。解析结果会被缓存在cachedOpt中以避免重复解析options.go。6.2 逐段转换与硬性校验Path(ctx, s, isDir)是对外主入口transform.go核心流程未启用任何转换时原样返回按顺序应用每条规则dir标签只作用于路径中除叶子外的目录段transformDirtransform.gofile标签且目标是文件时只对叶子段做baseOnly转换其余情况按/切分后逐段转换再拼回每个转换后的段必须通过validateSegmenttransform.go不允许转成空白串、不允许引入新的/最后做一道“段数守恒”检查转换前后/的数量必须一致否则记录错误并回退为原路径——这从机制上保证了转换绝不会把一条路径压平或拆层。调试时可用fs.Debugf输出transformed to: ...日志transform.go逐段追踪改名结果。6.3 顺序、冲突与非确定性convmv 命令帮助其中动态拼接了transform.Help()即本文档内容明确警告规则严格按用户指定的顺序依次执行rclone 不强制互斥prefix后接trimprefix、nfc后接nfd这类“冲突组合”是合法的语义由用户负责像replaceold:new这类规则可能让多个源文件映射到同一目标名并发传输下结果可能非确定性事后再跑rclone check可能误报差异官方建议优先用--dry-run预览但注意它无法体现非确定性转换的效果必要时用--transfers1关闭并发prefix类规则在bisync场景反复执行会产生叠加放大效应应尽量避免。6.4 单文件转换入口convmv带第二个参数时可只转换单个文件名Run分支中若指定了srcFileName则调用operations.TransformFileoperations.go否则对整个远端目录执行sync.Transformsync.go分别对应“单文件改名”与“整树改名”两种工作流。7. 测试与文档的生成机制单元测试lib/transform/transform_test.go 覆盖标签作用域TestFileTagOnFile、TestDirTagOnFile、TestAllTag等、多规则顺序应用如all,prefixtacall,prefixtic得到tictactoe/tictactoe/tictactoe以及第 5 节全部示例TestVarious同步链路层面的集成测试位于 fs/sync/sync_transform_test.go包括对非法字符all,prefixta/c引入斜杠应报错的负向用例。文档生成transform.md 首行标注“DO NOT EDIT”由 gen_help.go 生成——它维护命令表commandList与示例examples运行transform.SetOptionstransform.Path真实执行每个示例并回填输出再拼接Algo.Choices()、CharmapChoices.Choices()与encoder.ValidStrings()三个动态清单。触发方式为 transform.go 声明的//go:generate go run gen_help.go transform.md。这也解释了为什么本文示例输出与测试断言逐字一致文档、测试、实现三者同源。8. 实践建议先--dry-run后实跑convmv的改名不可逆任何replace/regex/trimprefix组合都应先预览。选对标签只改叶子文件名用默认file只改目录层级用dirUnicode 规范化、大小写、编码掩码等语义上应贯穿全路径的转换用all。规避同名冲突避免让两个不同源文件名转换后相等批量操作可加--transfers1。按字节上限的场景用truncate_bytes*当目标后端限制的是字节而非字符且文件名含多字节字符时truncate_bytes才是正确的度量且它能保证输出始终是合法 UTF-8。非法字符场景优先encoder掩码如规避 Windows 保留字符组合encoderColon,Question,Slash等比replace更贴近 rclone 既有的编码掩码语义。相关路径索引实现主体 lib/transform/transform.go、规则解析 lib/transform/options.go、字符集映射 lib/transform/cmap.go、文档生成器 lib/transform/gen_help.go、命令入口 cmd/convmv/convmv.go、遍历/同步/复制调用点 fs/march/march.go、fs/sync/sync.go、fs/operations/copy.go。【免费下载链接】rclonersync 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),仅供参考
返回列表