【Node】node自动批量转换文件类型脚本

const fs = require('node:fs/promises');
const path = require('node:path');

async function batchRenameExtension(directory, oldExtension, newExtension, includeSubdirectories = false) {
    const lowerOldExtension = oldExtension.toLowerCase();
    const lowerNewExtension = newExtension.toLowerCase();

    const normalizedOldExtension = lowerOldExtension.startsWith('.') ? lowerOldExtension : `.${lowerOldExtension}`;
    const normalizedNewExtension = lowerNewExtension.startsWith('.') ? lowerNewExtension : `.${lowerNewExtension}`;

    let count = 0;

    async function processDirectory(currentDir) {
        try {
            const items = await fs.readdir(currentDir);

            for (const item of items) {
                const itemPath = path.join(currentDir, item);
                const stats = await fs.stat(itemPath);

                if (stats.isFile() && item.toLowerCase().endsWith(normalizedOldExtension)) {
                    const newFilename = item.slice(0, -normalizedOldExtension.length) + normalizedNewExtension;
                    const newPath = path.join(currentDir, newFilename);

                    try {
                        await fs.rename(itemPath, newPath);
                        console.log(`已将 '${item}' 重命名为 '${newFilename}'`);
                        count++;
                    } catch (err) {
                        console.error(`重命名 '${item}' 失败: ${err}`);
                    }
                } else if (stats.isDirectory() && includeSubdirectories) {
                    await processDirectory(itemPath);
                }
            }
        } catch (err) {
            console.error(`读取目录 '${currentDir}' 失败: ${err}`);
        }
    }

    await processDirectory(directory);
    console.log(`\n共处理了 ${count} 个文件。`);
}

async function main() {
    const targetDirectory = await prompt('请输入要处理的目录路径: ');
    const oldExt = await prompt('请输入要替换的原始文件后缀 (例如: .tif): ');
    const newExt = await prompt('请输入要替换为的新文件后缀 (例如: .png): ');
    const includeSubInput = await prompt('是否包含子目录中的文件? (yes/no, 默认为 no): ');
    const includeSub = includeSubInput.toLowerCase() === 'yes';

    try {
        const stats = await fs.stat(targetDirectory);
        if (!stats.isDirectory()) {
            console.error('指定的目录不存在!');
            return;
        }
        await batchRenameExtension(targetDirectory, oldExt, newExt, includeSub);
    } catch (err) {
        console.error('发生错误:', err);
    }
}

async function prompt(question) {
    const readline = require('node:readline').createInterface({
        input: process.stdin,
        output: process.stdout,
    });

    return new Promise((resolve) => {
        readline.question(question, (answer) => {
            readline.close();
            resolve(answer);
        });
    });
}

main();

 

posted @ 2025-03-18 18:17  维多利亚的巴黎世家  阅读(22)  评论(0)    收藏  举报