使用fs.rename批量重命名不同扩展名文件仅成功9个,如何解决?
批量重命名文件问题解决
需求说明
原文件名格式:
1-BLUE-RED-ITEM-.gif 2-GREEN-ORANGE-ITEM-.png 3-PINK-GREEN-ITEM-.gif ...
目标文件名格式:
1.gif 2.png 3.gif ...
当前代码问题
你提供的代码仅能处理前9个文件,后续文件无法正常重命名且进程提前退出,核心问题如下:
file.includes(fileNum)的匹配逻辑有缺陷:数字超过9后(如10),会错误匹配所有包含该数字片段的文件(如1、10、11等),导致逻辑混乱。fs.renameSync是同步方法,无需传入回调函数,代码中的回调不会被执行。- 异步函数调用未加
await,进程会在重命名操作完成前提前退出。 file.slice(-4)获取扩展名的方式不可靠,无法适配不同长度的扩展名(如.svg)。
当前代码:
const reNameImages = async(file, batchNumber, fileNum) => { fs.renameSync(batchNumber + "/" + file, batchNumber + "/" + fileNum + file.slice(-4), function(err) { if (err) { console.log("Error" + (err)); } }); console.log("File Renamed:"); console.log(file); } const secondRenameImages = async(batchNumber, thisFile) => { let fileNum = thisFile; fs.readdirSync(batchNumber).forEach(file => { if (file.includes(fileNum)) { reNameImages(file, batchNumber, fileNum); } }); } const saveMetaDataFiles = async(fileAmount, batchNumber) => { var thisCount = 1; for (let i = thisCount; i <= fileAmount; i++) { saveMetaDataSingleFile(i); secondRenameImages(batchNumber, i); thisCount++; } };
解决方案
同步版本代码
遍历目录所有文件,用正则精准提取开头数字,配合path.extname可靠获取扩展名,同步完成重命名:
const fs = require('fs'); const path = require('path'); // 替换为你的目标目录路径 const targetDir = '你的目录路径'; // 读取目录下所有文件 const files = fs.readdirSync(targetDir); files.forEach(file => { const fullPath = path.join(targetDir, file); // 跳过子目录 if (fs.statSync(fullPath).isDirectory()) return; // 用正则匹配文件名开头的连续数字部分 const numMatch = file.match(/^(\d+)-/); if (!numMatch) { console.log(`跳过不符合格式的文件: ${file}`); return; } const fileNum = numMatch[1]; // 正确获取文件扩展名 const ext = path.extname(file); const newFileName = `${fileNum}${ext}`; const newFullPath = path.join(targetDir, newFileName); try { fs.renameSync(fullPath, newFullPath); console.log(`重命名成功: ${file} → ${newFileName}`); } catch (err) { console.error(`重命名失败 ${file}:`, err.message); } });
异步版本代码
如果目录文件较多,推荐用异步方式避免阻塞:
const fs = require('fs').promises; const path = require('path'); async function batchRenameFiles(targetDir) { try { const files = await fs.readdir(targetDir); for (const file of files) { const fullPath = path.join(targetDir, file); const stats = await fs.stat(fullPath); // 跳过子目录 if (stats.isDirectory()) continue; const numMatch = file.match(/^(\d+)-/); if (!numMatch) { console.log(`跳过不符合格式的文件: ${file}`); continue; } const fileNum = numMatch[1]; const ext = path.extname(file); const newFileName = `${fileNum}${ext}`; const newFullPath = path.join(targetDir, newFileName); await fs.rename(fullPath, newFullPath); console.log(`重命名成功: ${file} → ${newFileName}`); } console.log('所有文件重命名完成'); } catch (err) { console.error('批量重命名出错:', err.message); } } // 替换为你的目录路径并调用 batchRenameFiles('你的目录路径');
关键改进点
- 用正则
/^(\d+)-/精准匹配文件名开头的连续数字,彻底避免误匹配。 - 用
path.extname获取扩展名,适配所有合法扩展名格式。 - 同步版本逻辑简单直接;异步版本用
for...of配合await确保所有操作顺序完成,避免进程提前退出。
内容的提问来源于stack exchange,提问作者Meltxx
相关产品推荐
相关产品推荐

