JS 脚本规则
想用文本文件的第一行做文件名?想根据文件大小智能分类?普通规则做不到的复杂重命名,JS 脚本都能实现。
这个功能能帮你
- 读取文件内容做文件名:用 txt/md 文件的第一行作为新文件名,自动整理笔记
- 根据文件大小分类:给文件加上
[SMALL]、[MEDIUM]、[LARGE]标签,一眼看出大小 - 配置文件批量重命名:在文件夹放个
rename_rules.txt配置文件,按规则自动处理 - JavaScript 逻辑处理:if/else、正则、日期计算,写代码能做的都能做
快速上手(3步)
- 点击"添加规则"按钮 → 选 "JS 脚本"
- 选个示例开始:点击"Demo 示例"下拉框,选一个接近你需求的示例
- 先点预览看效果,没问题再点应用
具体例子
例子1:强制修改扩展名
❌ 原文件:document.txt、report.docx、image.png
😫 问题:想把所有文件的扩展名统一改成 .zip
✅ 代码:
function main(file_name, file_path, file_index) {
// 强制所有文件使用 .zip 扩展名
return getFileNameExt(file_name).name + ".zip";
}✅ 结果:document.zip、report.zip、image.zip
为什么这样设置:
getFileNameExt帮你分离文件名和扩展名,只需简单拼接即可。这是最简单的重命名逻辑。
例子2:用文本文件首行做前缀
❌ 原文件:note.txt(内容第一行是"项目计划")
😫 问题:笔记文件名太随意,想用首行内容做前缀方便识别
✅ 代码:
function main(file_name, file_path, file_index) {
if (file_path == undefined) {
return file_name;
}
const file_data = getFileNameExt(file_name);
if (file_data.ext === ".txt" || file_data.ext === ".md") {
try {
// 读取文件内容
const content = api.readTextFile(file_path);
const lines = content.split('\n');
const firstLine = lines[0] ? lines[0].trim() : '';
if (firstLine) {
// 清理文件名中的非法字符
const cleanPrefix = firstLine
.replace(/[<>:"/\\|?*]/g, '_')
.substring(0, 20);
console.log("首行前缀", cleanPrefix);
return cleanPrefix + "_" + file_name;
}
} catch (error) {
console.log("读取文件失败", error.message);
}
}
return file_name;
}✅ 结果:项目计划_note.txt
为什么这样设置:
- 先判断
file_path是否存在(某些情况下可能为空)- 只处理
.txt和.md文件- 用
try...catch避免读取失败导致中断- 清理非法字符,限制前缀长度避免文件名过长
例子3:根据文件大小标注
❌ 原文件:photo.jpg(5.2MB)
😫 问题:想看文件名就知道大概大小,方便筛选
✅ 代码:
function main(file_name, file_path, file_index) {
if (file_path == undefined) {
return file_name;
}
const file_data = getFileNameExt(file_name);
try {
const fileSizeBytes = api.getFileSize(file_path);
let sizeCategory = "";
let sizeLabel = "";
if (fileSizeBytes < 1024) {
sizeCategory = "TINY";
sizeLabel = fileSizeBytes + "B";
} else if (fileSizeBytes < 1024 * 1024) {
sizeCategory = "SMALL";
sizeLabel = Math.round(fileSizeBytes / 1024) + "KB";
} else if (fileSizeBytes < 1024 * 1024 * 10) {
sizeCategory = "MEDIUM";
sizeLabel = Math.round(fileSizeBytes / (1024 * 1024)) + "MB";
} else {
sizeCategory = "LARGE";
sizeLabel = Math.round(fileSizeBytes / (1024 * 1024)) + "MB";
}
return `[${sizeCategory}]_${sizeLabel}_${file_data.name}${file_data.ext}`;
} catch (error) {
console.log("获取文件大小失败", error.message);
return file_name;
}
}✅ 结果:[MEDIUM]_5MB_photo.jpg
为什么这样设置:
- 用 if/else 条件判断将文件分为 4 个等级
- 自动换算单位(B/KB/MB)便于阅读
- 模板字符串(反引号)方便拼接多个变量
函数和 API 参考
main 函数签名
所有 JS 脚本必须包含一个 main 函数,这是程序的入口:
function main(file_name, file_path, file_index) {
// 你的重命名逻辑
return 'new_name.txt' // 必须返回新文件名
}参数说明
| 参数 | 类型 | 说明 | 示例 |
|---|---|---|---|
file_name | string | 原始文件名(含扩展名) | "document.txt" |
file_path | string | undefined | 文件绝对路径(可能为 undefined) | "/Users/xxx/document.txt" |
file_index | number | 文件索引(从 0 开始) | 0, 1, 2 |
重要:file_path 在某些情况下可能为 undefined(比如仅预览模式),使用前必须先判断:
if (file_path == undefined) {
return file_name;
}内置 API
| API | 功能 | 返回值 | 限制 |
|---|---|---|---|
api.readTextFile(path) | 读取文本文件 | string | 最大 2MB |
api.readLines(path) | 按行读取文件 | string[] | 最大 2MB |
api.readBytes(path, offset, length) | 读取字节范围 | Uint8Array | 最大 256KB |
api.getFileSize(path) | 获取文件大小(字节) | number | - |
使用示例:
// 读取整个文件
const content = api.readTextFile(file_path);
// 按行读取
const lines = api.readLines(file_path);
console.log("第一行:", lines[0]);
// 读取文件头部(前 100 字节)
const header = api.readBytes(file_path, 0, 100);
// 获取文件大小
const size = api.getFileSize(file_path);
console.log("文件大小:", size, "字节");Helper 函数
getFileNameExt(file_name)
分离文件名和扩展名的工具函数:
const result = getFileNameExt("document.txt");
// 返回: { name: "document", ext: ".txt" }
const result2 = getFileNameExt("README");
// 返回: { name: "README", ext: "" }返回值:
name:不含扩展名的文件名ext:扩展名(含点号前缀,如.txt;无扩展名则为空字符串)
平台功能差异
Renamio 支持两个平台,部分功能存在差异:
uTools 平台
- ✅ AI 代码生成:描述需求,AI 帮你写代码
- ✅ AI 微调:改进现有代码的功能
- ✅ 使用浏览器控制台查看
console.log输出
Tauri 平台
- ✅ 日志窗口:独立窗口显示
console.log输出,打开方式:切换"日志窗口"开关 - ✅ 测试代码:不实际重命名,只测试代码是否正常运行
- ✅ 更安全的沙盒环境
核心功能完全相同:两个平台的 main 函数、内置 API、Helper 函数完全一致。
内置示例详解
点击"Demo 示例"下拉框可以快速加载 6 个内置示例:
1. Demo: Basic usage
完整的 API 文档注释,展示所有参数和内置函数的使用方法。适合初学者了解功能。
2. Convert extension to .zip
强制修改扩展名为 .zip,演示 getFileNameExt 的基本用法。
3. Delete last 2 characters
删除文件名末尾 2 个字符,演示边界检查(字符不足时保持原名)。
4. Use first line as prefix
用文本文件首行做前缀,演示:
api.readTextFile读取文件- 文件类型判断(只处理
.txt和.md) - 非法字符清理
5. Annotate with file size
用文件大小标注文件名,演示:
api.getFileSize获取文件大小- 条件判断进行分类(TINY/SMALL/MEDIUM/LARGE)
- 单位换算和格式化输出
6. Rename by config file
根据同目录的 rename_rules.txt 配置文件重命名,演示:
- 读取配置文件
- 解析规则格式(
pattern->replacement) - 支持通配符
* - 模板变量替换(
{name},{ext},{index},{date})
配置文件示例 (rename_rules.txt):
# 注释行,以 # 开头会被忽略
*.txt->文本_{name}{ext}
*.jpg->照片_{index}{ext}
*->文件_{date}_{name}{ext}常见问题
❓ 为什么我的代码不执行?
-
检查是否包含
main函数 代码必须包含function main(file_name, file_path, file_index) { ... } -
确保
main函数有return必须返回新文件名,否则保持原名不变 -
查看日志输出
- Tauri 平台:打开"日志窗口"开关
- uTools 平台:打开浏览器开发者工具(F12)
-
检查语法错误 JavaScript 语法错误会导致整个脚本无法执行
❓ 怎么调试代码?
使用 console.log 输出中间变量:
function main(file_name, file_path, file_index) {
console.log("文件名:", file_name);
console.log("文件路径:", file_path);
console.log("文件索引:", file_index);
const file_data = getFileNameExt(file_name);
console.log("分离结果:", file_data);
return file_name;
}查看输出:
- Tauri 平台:切换"日志窗口"开关,会打开独立窗口显示所有日志
- uTools 平台:按 F12 打开浏览器控制台查看
Tauri 测试功能:
点击"测试代码"按钮,使用测试数据(file_name="test.txt", file_index=0)运行代码,不会实际重命名文件。
❓ 读取文件时报错怎么办?
-
检查
file_path是否为undefinedif (file_path == undefined) { console.log("文件路径为空,跳过处理"); return file_name; } -
用
try...catch包裹文件读取代码try { const content = api.readTextFile(file_path); // 处理内容... } catch (error) { console.log("读取失败:", error.message); return file_name; // 失败时保持原名 } -
确认文件大小在限制范围内
- 文本读取(
readTextFile,readLines):最大 2MB - 字节读取(
readBytes):最大 256KB
- 文本读取(
-
检查文件是否存在 某些情况下文件路径可能失效,确保文件真实存在
❓ 如何处理不同类型的文件?
根据扩展名进行判断:
function main(file_name, file_path, file_index) {
const file_data = getFileNameExt(file_name);
if (file_data.ext === ".txt" || file_data.ext === ".md") {
// 处理文本文件
return "文本_" + file_name;
} else if (file_data.ext === ".jpg" || file_data.ext === ".png") {
// 处理图片文件
return "图片_" + file_name;
} else {
// 其他文件
return file_name;
}
}注意事项:
- ⚠️ 文件路径可能为空:使用
file_path前必须先判断if (file_path == undefined) - ⚠️ 必须做错误处理:文件读取可能失败,用
try...catch避免整个流程中断 - ⚠️ 返回值必须是字符串:
main函数必须return新文件名,否则保持原名 - ⚠️ 非法字符会被过滤:文件名中的
[\\/:*?"<>|]等字符系统会自动过滤或替换 - ⚠️ 扩展名注意大小写:
.jpg和.JPG是不同的,建议统一转小写比较:file_data.ext.toLowerCase() === ".jpg"
进阶技巧
配合其他规则使用
- ✅ 配合"序号生成":JS 脚本处理复杂逻辑(如读取文件内容),序号规则生成统一编号
- ✅ 配合"日期规则":JS 脚本读取文件元数据,日期规则格式化时间戳
- ✅ 配合"正则规则":JS 脚本做复杂判断(如文件类型分类),正则规则做文本替换
使用正则表达式
JavaScript 内置正则表达式支持:
function main(file_name, file_path, file_index) {
// 提取文件名中的数字
const match = file_name.match(/\d+/);
if (match) {
const number = parseInt(match[0]);
return `序号${number}_${file_name}`;
}
return file_name;
}处理日期和时间
使用 JavaScript 的 Date 对象:
function main(file_name, file_path, file_index) {
const now = new Date();
const dateStr = now.toISOString().slice(0, 10); // 2024-01-15
const file_data = getFileNameExt(file_name);
return `${dateStr}_${file_data.name}${file_data.ext}`;
}批量处理序号
利用 file_index 参数生成自定义序号:
function main(file_name, file_path, file_index) {
// 从 1 开始,补齐 3 位数字
const serial = String(file_index + 1).padStart(3, '0');
const file_data = getFileNameExt(file_name);
return `${serial}_${file_data.name}${file_data.ext}`;
}