跨平台文件名规范性检查与处理工具
1 | wget -qO- https://haies.cn/assets/checkname.js |
使用说明
checkname 是一个基于 Node.js 的命令行工具,用于检查和自动修复文件及目录名称,确保它们能够同时在 Windows 11、macOS 和 Ubuntu 系统中正常使用,便于跨平台文件共享。工具会检查文件名是否包含禁止字符、是否超长、是否存在空格等不可见字符,并按照预定策略进行规范化处理,同时自动处理重名冲突。
安装与运行
- 环境要求:Node.js 12.0 或更高版本(建议使用 LTS 版本)。
- 获取脚本:将脚本保存为
checkname.js。 - 运行方式:在终端中执行
node checkname.js [参数] [目录1] [目录2] ...
基本用法
1 | node checkname.js [-p] <目录1> [<目录2> ...] |
-p:处理模式。- 若指定此参数,脚本会尝试读取目标目录下最新的日志文件,并根据日志记录对不符合规范的文件/目录进行重命名操作。
- 如果目录下没有日志文件,则先执行完整检查并生成日志,然后立即根据该日志进行处理。
- 处理完成后,日志文件会被更新,记录每个条目的处理结果(新路径、状态等)。
- 不指定
-p:仅检查模式。脚本遍历目录,找出所有不符合规范的文件和目录,并将记录保存到新生成的日志文件中(不会修改任何文件)。
使用示例
示例 1:仅检查目录 /home/user/share
1 | node checkname.js /home/user/share |
输出:
1 | 处理目录: /home/user/share |
此时目录下会生成日志文件,记录不合规条目的详细信息。你可以查看日志决定是否进行下一步处理。
示例 2:处理目录(基于已有日志)
1 | node checkname.js -p /home/user/share |
假设目录下已有日志 checkname_20250302_143022.jsonl:
1 | 处理目录: /home/user/share |
脚本会读取日志,重命名其中两个文件/目录,并更新日志状态。跳过的条目可能是因为原名称已合规(无需修改)。
示例 3:处理多个目录,且目录无现有日志
1 | node checkname.js -p /mnt/data /mnt/docs |
输出:
1 | 处理目录: /mnt/data |
示例 4:查看日志内容
1 | cat /home/user/share/checkname_20250302_143022.jsonl |
输出示例:
1 | {"type":"file","originalPath":"/home/user/share/a*b?.txt","newPath":null,"issues":["invalid_char"],"status":"pending","timestamp":"2025-03-02T14:30:22.123Z"} |
处理后的日志会更新 newPath 和 status。
相关说明
1. 规范性规则
- 禁止字符:包含以下任一字符的名称被视为不合规:
<>:"/\|?*(Windows 文件系统禁止的字符)- ASCII 控制字符(0x00–0x1F)
- 所有 Unicode 空白字符(包括空格、制表符、换行符等)
- 长度限制:文件名(包括扩展名)的 UTF-8 编码字节数不得超过 255 字节(这是 Linux 的极限值,也是 Windows 和 macOS 的安全上限)。中文字符通常占 3 字节,需要特别注意。
- 忽略条目:脚本会自动跳过以下类型的文件和目录(及其内部所有内容):
- 以点(
.)开头的隐藏文件/目录 - 名称为
node_modules、dist、build、bin、debug的目录(不区分大小写)
- 以点(
2. 处理策略
当发现不合规的名称时,按以下顺序进行修正:
- 删除非法字符:移除所有禁止字符。
- 长度缩减:如果删除非法字符后仍超长,则对主名(不含扩展名)依次应用以下规则,直到字节数达标:
- 删除特殊字符(非字母、数字、下划线
_、连字符-)。 - 将连续重复 4 次以上的字符缩减为 4 次(例如
"aaaaa"→"aaaa")。 - 从主名末尾逐个删除字符。
- 删除特殊字符(非字母、数字、下划线
- 重名冲突处理:修正后的名称若与同目录下已有条目重名,则自动添加序号
(1)、(2)…… 直至不冲突。添加序号时会确保总长度不超限,必要时会进一步截断主名。
3. 日志文件
命名格式:
checkname_YYYYMMDD_HHMMSS.jsonl(例如checkname_20250302_143022.jsonl),保存在被分析的目录下。格式:JSON Lines,每行一条记录,包含以下字段:
1
2
3
4
5
6
7
8
9{
"type": "file|dir", // 条目类型
"originalPath": "/绝对/路径/原名称", // 原始完整路径
"newPath": "/绝对/路径/新名称", // 处理后的路径(仅处理模式有值)
"issues": ["invalid_char", "too_long"], // 不合规原因
"status": "pending|processed|error|skipped", // 状态
"error": "错误信息(如果有)", // 处理失败时的错误信息
"timestamp": "2025-03-02T14:30:22.123Z" // 记录生成时间
}作用:日志既是检查结果的记录,也是处理模式的输入。处理模式只会处理
status为pending的条目,并更新其状态为processed、error或skipped。
4. 处理模式详解
- 基于现有日志:若目录下已有日志文件,脚本会自动选择最新的一个,读取其中的记录,然后尝试处理所有状态为
pending的条目。处理完成后,日志文件会被覆盖更新。 - 无日志时:如果目录下没有日志文件,则先执行完整检查,生成新日志,然后立即根据该日志进行处理。这相当于一次完成“检查+处理”。
- 重复运行:可以多次运行处理模式,每次只会处理尚未处理的条目(
pending状态)。已处理(processed)、出错(error)或跳过(skipped)的记录不会重复操作。
注意事项
- 备份重要数据:处理模式会实际修改文件名,建议首次使用时先运行不带
-p的检查模式,查看日志确认后再执行处理。 - 权限问题:确保脚本对目标目录有读写权限,否则处理可能失败。
- 跨平台兼容:修正后的文件名仍可能在某些极端情况下不兼容(例如保留字如
CON、PRN等,Windows 有保留设备名),本工具未处理这些情况,请自行留意。 - 日志累积:多次运行处理模式会不断更新同一个日志文件,如需保留历史记录,请手动备份旧日志。
- 并发安全:脚本为串行处理,不会同时修改多个文件,避免冲突。