JS Script Rule
Want to use a text file's first line as the filename? Want intelligent categorization by file size? Complex renaming that regular rules can't do - JS scripts can do it all.
This Feature Helps You
- Use file content as filename: Use the first line of txt/md files as new filename, auto-organize notes
- Categorize by file size: Add tags like
[SMALL],[MEDIUM],[LARGE]to files, see size at a glance - Batch rename by config file: Put a
rename_rules.txtconfig file in folder, auto-process by rules - JavaScript logic processing: if/else, regex, date calculations - anything you can code, you can do
Quick Start (3 Steps)
- Click "Add Rule" button β Select "JS Script"
- Pick an example to start: Click "Demo Examples" dropdown, select one close to your needs
- Preview first, apply if it looks good
Detailed Examples
Example 1: Force Change Extension
β Original: document.txt, report.docx, image.png
π« Problem: Want to change all file extensions to .zip
β
Code:
function main(file_name, file_path, file_index) {
// Force all files to use .zip extension
return getFileNameExt(file_name).name + ".zip";
}β
Result: document.zip, report.zip, image.zip
Why this setup:
getFileNameExthelps you separate filename and extension, just need simple concatenation. This is the simplest renaming logic.
Example 2: Use Text File First Line as Prefix
β Original: note.txt (first line content is "Project Plan")
π« Problem: Note filenames are too casual, want to use first line content as prefix for easy identification
β
Code:
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 {
// Read file content
const content = api.readTextFile(file_path);
const lines = content.split('\n');
const firstLine = lines[0] ? lines[0].trim() : '';
if (firstLine) {
// Clean illegal characters from filename
const cleanPrefix = firstLine
.replace(/[<>:"/\\|?*]/g, '_')
.substring(0, 20);
console.log("First line prefix", cleanPrefix);
return cleanPrefix + "_" + file_name;
}
} catch (error) {
console.log("Failed to read file", error.message);
}
}
return file_name;
}β
Result: Project_Plan_note.txt
Why this setup:
- First check if
file_pathexists (may be empty in some cases)- Only process
.txtand.mdfiles- Use
try...catchto avoid read failures causing interruption- Clean illegal characters, limit prefix length to avoid filename too long
Example 3: Annotate by File Size
β Original: photo.jpg (5.2MB)
π« Problem: Want to know approximate size from filename, convenient for filtering
β
Code:
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("Failed to get file size", error.message);
return file_name;
}
}β
Result: [MEDIUM]_5MB_photo.jpg
Why this setup:
- Use if/else conditions to classify files into 4 levels
- Auto-convert units (B/KB/MB) for readability
- Template strings (backticks) make concatenating multiple variables convenient
Function and API Reference
main Function Signature
All JS scripts must include a main function, this is the program entry point:
function main(file_name, file_path, file_index) {
// Your renaming logic
return 'new_name.txt' // Must return new filename
}Parameter Description
| Parameter | Type | Description | Example |
|---|---|---|---|
file_name | string | Original filename (with extension) | "document.txt" |
file_path | string | undefined | Absolute file path (may be undefined) | "/Users/xxx/document.txt" |
file_index | number | File index (starts from 0) | 0, 1, 2 |
Important: file_path may be undefined in some cases (like preview-only mode), must check before using:
if (file_path == undefined) {
return file_name;
}Built-in APIs
| API | Function | Return Value | Limit |
|---|---|---|---|
api.readTextFile(path) | Read text file | string | Max 2MB |
api.readLines(path) | Read file by lines | string[] | Max 2MB |
api.readBytes(path, offset, length) | Read byte range | Uint8Array | Max 256KB |
api.getFileSize(path) | Get file size (bytes) | number | - |
Usage Examples:
// Read entire file
const content = api.readTextFile(file_path);
// Read by lines
const lines = api.readLines(file_path);
console.log("First line:", lines[0]);
// Read file header (first 100 bytes)
const header = api.readBytes(file_path, 0, 100);
// Get file size
const size = api.getFileSize(file_path);
console.log("File size:", size, "bytes");Helper Functions
getFileNameExt(file_name)
Utility function to separate filename and extension:
const result = getFileNameExt("document.txt");
// Returns: { name: "document", ext: ".txt" }
const result2 = getFileNameExt("README");
// Returns: { name: "README", ext: "" }Return value:
name: Filename without extensionext: Extension (with dot prefix like.txt; empty string if no extension)
Platform Feature Differences
Renamio supports two platforms with some functional differences:
uTools Platform
- β AI code generation: Describe requirements, AI writes code for you
- β AI fine-tuning: Improve existing code functionality
- β
Use browser console to view
console.logoutput
Tauri Platform
- β
Log window: Independent window displays
console.logoutput, open by toggling "Log Window" switch - β Test code: Don't actually rename, only test if code runs normally
- β More secure sandbox environment
Core functionality is identical: Both platforms have identical main function, built-in APIs, and helper functions.
Built-in Example Details
Click "Demo Examples" dropdown to quickly load 6 built-in examples:
1. Demo: Basic usage
Complete API documentation comments, showing usage of all parameters and built-in functions. Suitable for beginners to understand functionality.
2. Convert extension to .zip
Force change extension to .zip, demonstrates basic usage of getFileNameExt.
3. Delete last 2 characters
Delete last 2 characters from filename, demonstrates boundary checking (keep original name if insufficient characters).
4. Use first line as prefix
Use text file first line as prefix, demonstrates:
api.readTextFileto read files- File type checking (only process
.txtand.md) - Illegal character cleaning
5. Annotate with file size
Annotate filename with file size, demonstrates:
api.getFileSizeto get file size- Conditional categorization (TINY/SMALL/MEDIUM/LARGE)
- Unit conversion and formatted output
6. Rename by config file
Rename based on rename_rules.txt config file in same directory, demonstrates:
- Reading config file
- Parsing rule format (
pattern->replacement) - Wildcard
*support - Template variable replacement (
{name},{ext},{index},{date})
Config file example (rename_rules.txt):
# Comment lines, starting with # will be ignored
*.txt->text_{name}{ext}
*.jpg->photo_{index}{ext}
*->file_{date}_{name}{ext}Common Questions
β Why isn't my code executing?
-
Check if
mainfunction is included Code must containfunction main(file_name, file_path, file_index) { ... } -
Ensure
mainfunction hasreturnMust return new filename, otherwise original name stays unchanged -
Check log output
- Tauri platform: Open "Log Window" switch
- uTools platform: Open browser developer tools (F12)
-
Check for syntax errors JavaScript syntax errors will prevent entire script from executing
β How to debug code?
Use console.log to output intermediate variables:
function main(file_name, file_path, file_index) {
console.log("Filename:", file_name);
console.log("File path:", file_path);
console.log("File index:", file_index);
const file_data = getFileNameExt(file_name);
console.log("Split result:", file_data);
return file_name;
}View output:
- Tauri platform: Toggle "Log Window" switch, opens independent window showing all logs
- uTools platform: Press F12 to open browser console
Tauri test feature:
Click "Test Code" button, runs code with test data (file_name="test.txt", file_index=0), won't actually rename files.
β What to do when file reading errors occur?
-
Check if
file_pathisundefinedif (file_path == undefined) { console.log("File path is empty, skipping"); return file_name; } -
Wrap file read code with
try...catchtry { const content = api.readTextFile(file_path); // Process content... } catch (error) { console.log("Read failed:", error.message); return file_name; // Keep original name on failure } -
Confirm file size is within limits
- Text reading (
readTextFile,readLines): Max 2MB - Byte reading (
readBytes): Max 256KB
- Text reading (
-
Check if file exists In some cases file path may be invalid, ensure file actually exists
β How to handle different file types?
Judge based on extension:
function main(file_name, file_path, file_index) {
const file_data = getFileNameExt(file_name);
if (file_data.ext === ".txt" || file_data.ext === ".md") {
// Handle text files
return "text_" + file_name;
} else if (file_data.ext === ".jpg" || file_data.ext === ".png") {
// Handle image files
return "image_" + file_name;
} else {
// Other files
return file_name;
}
}Notes:
- β οΈ File path may be empty: Must check
if (file_path == undefined)before usingfile_path - β οΈ Must handle errors: File reads may fail, use
try...catchto avoid interrupting entire process - β οΈ Return value must be string:
mainfunction mustreturnnew filename, otherwise keeps original name - β οΈ Illegal characters will be filtered: Characters like
[\\/:*?"<>|]in filename will be automatically filtered or replaced by system - β οΈ Watch extension case:
.jpgand.JPGare different, recommend converting to lowercase for comparison:file_data.ext.toLowerCase() === ".jpg"
Advanced Tips
Combine with Other Rules
- β Combine with "Sequence": JS script handles complex logic (like reading file content), sequence rule generates uniform numbering
- β Combine with "Date Rule": JS script reads file metadata, date rule formats timestamps
- β Combine with "Regex Rule": JS script does complex decisions (like file type categorization), regex rule does text replacement
Use Regular Expressions
JavaScript has built-in regex support:
function main(file_name, file_path, file_index) {
// Extract numbers from filename
const match = file_name.match(/\d+/);
if (match) {
const number = parseInt(match[0]);
return `serial${number}_${file_name}`;
}
return file_name;
}Handle Dates and Times
Use JavaScript's Date object:
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}`;
}Batch Process Serial Numbers
Use file_index parameter to generate custom serial numbers:
function main(file_name, file_path, file_index) {
// Start from 1, pad to 3 digits
const serial = String(file_index + 1).padStart(3, '0');
const file_data = getFileNameExt(file_name);
return `${serial}_${file_data.name}${file_data.ext}`;
}What to Check Out Next?
- Conditional Replace: If your logic isn't too complex, try conditional replace rule (no coding needed)
- Regular Expression: Powerful text pattern matching and replacement
- Sequence: Batch add serial numbers to files