js使用oclif开发命令行工具实现批量修改文件名
作者:双羽
前端开发工作中常用的很多CLI命令相信大家已经很熟悉了,很方便很实用,能够快速帮助你创建项目,快速执行某些重复性操作,下面我们就来学习一下如何使用CLI命令批量修改文件名吧
前言
前端开发工作中常用的很多 CLI 命令相信大家已经很熟悉了,很方便很实用,能够快速帮助你创建项目,快速执行某些重复性操作。
oclif
我们 github.com/oclif/oclif 库来作为 CLI 的基础框架,这个官方文档写的很详细,我们这里简单的扩展说一下,并且实践一个 demo。
设计一个批量修改文件名的小工具
我们设计一个批量更改文件名字的小工具,它可以帮助我们将某个目录的下所有文件,按照自定义的规则来进行批量重命名,这个工具
设计我们的命令用法
我们希望这样使用命令即可批量重命名目录下的所有文件。
./cl rename ./test -R -N test_{{index}}_{{time}}_{{st}}
其中 ./cl 是 ln -s /bin/dev
我们想设计的参数
{{name}}
代表原始文件名{{index}}
代表递归指数:1,2,3,4{{time}}
代表时间:2022-8-23_11-39{{st}}
代表时间戳:1661226082464-R
代表是否开启目录深层递归-N XXXX
批量重命名后的名字格式
列如我们可以这样用:
./cl rename ./test -R -N test_{{index}}_{{time}}_{{st}} 正在执行批量重命名命令,参数:{ path: './test' },{ deep: true, name: 'test_{{index}}_{{time}}_{{st}}' } 读取目录: ./test 读取目录: test/sub 读取目录: test/sub/commands 读取目录: test/sub/commands/hello 重命名文件: test/sub/commands/hello/test_4_2022-8-18_19-47_1661225596495.ts --> test_0_2022-8-18_19-47_1661225679878.ts 重命名文件: test/sub/commands/hello/test_5_2022-8-18_19-47_1661225596495.js --> test_1_2022-8-18_19-47_1661225679879.js 重命名文件: test/sub/commands/hello/test_6_2022-8-18_19-47_1661225596496.ts --> test_2_2022-8-18_19-47_1661225679879.ts 重命名文件: test/sub/commands/hello/test_7_2022-8-18_19-47_1661225596496.js --> test_3_2022-8-18_19-47_1661225679879.js 重命名文件: test/sub/commands/hello/test_8_2022-8-18_19-47_1661225596496.ts --> test_4_2022-8-18_19-47_1661225679879.ts 重命名文件: test/sub/commands/hello/test_9_2022-8-18_19-47_1661225596496.js --> test_5_2022-8-18_19-47_1661225679879.js 读取目录: test/sub/commands/setup 重命名文件: test/sub/commands/setup/index.d.ts --> test_6_2022-8-18_19-47_1661225679879.ts 重命名文件: test/sub/commands/setup/index.js --> test_7_2022-8-18_19-47_1661225679879.js 重命名文件: test/sub/index.d.ts --> test_8_2022-8-18_19-47_1661225679879.ts 重命名文件: test/sub/index.js --> test_9_2022-8-18_19-47_1661225679880.js 重命名文件: test/sub/test_3_2022-8-23_10-52_1661225596495 --> test_10_2022-8-23_10-52_1661225679880 重命名文件: test/test_0_2022-8-23_10-52_1661225596494 --> test_11_2022-8-23_10-52_1661225679880 重命名文件: test/test_1_2022-8-16_18-1_1661225596495.png --> test_12_2022-8-16_18-1_1661225679880.png 重命名文件: test/test_2_2022-7-18_14-32_1661225596495.json --> test_13_2022-7-18_14-32_1661225679880.json 重命名文件: test/图片2.jpg --> test_15_2022-6-24_15-12_1661225679880.jpg 重命名文件: test/矩阵点背景图 2.png --> test_17_2022-8-12_17-23_1661225679881.png 重命名文件: test/矩阵点背景图.png --> test_18_2022-8-12_17-23_1661225679881.png
自动的递归所有文件,并且全部以某个格式进行命名
源码实现
目录结构
首先跟随官方文档所说的那样,安装并生成 Hello world 程序,再进行我们自定义命令的编写。接下来我们新建一个命令。
- src/commands/rename/index.ts
- 在 rename 目录下新建 index.ts 之后,框架会为我们自动注册 rename 命令。
代码中我写了注释,通过配合代码阅读相信会更有用。
import { Command, Flags, CliUx } from "@oclif/core"; import * as fs from "fs-extra"; import * as path from "path"; // 执行命令: // ./cl rename ./test -R -N test_{{index}}_{{time}}_{{st}} export class Rename extends Command { static description = "description of this example command"; // 注册标识参数:--name 和 --deep,并且设置简称 static flags = { name: Flags.string({ char: "N" }), deep: Flags.boolean({ char: "R" }), }; // 注册参数,即 rename 空格后的第一段文字,这里是 ./test static args = [{ name: "path" }]; private index = 0; // 命令解析完毕后,执行此方法 async run() { const { args } = await this.parse(Rename); const { flags } = await this.parse(Rename); this.log("正在执行批量重命名命令,参数:%s,%s", args, flags); // 遍历目录并给每一个文件执行规则程序 this.wake(args.path, flags.deep, (path: string) => { this.rule(path, flags.name); }); } // 递归遍历目录 wake(root: string, recursive = false, callback = (path: string) => {}): void { console.log("读取目录:", root); for (const filename of fs.readdirSync(root)) { const absPath = path.normalize(path.join(root, filename)); const file = fs.statSync(absPath); if (file.isDirectory() && recursive) { this.wake(absPath, recursive, callback); continue; } try { callback(absPath); } catch (error) { console.log(error); } } } // 文件名规则注册 rule(filePath: string, nameRules?: string) { const fileName = path.basename(filePath); // 规则程序执行,替换关键字 // 目前只做这么几个规则,以后看情况加,扩展性也不错,可以单独分到 services 层做一层分离,可读性更高 // 这里注册了 {{index}} {{time}} 等关键字 let newFileName = this.keyword( String(nameRules), "index", () => this.index++ ); newFileName = this.keyword(newFileName, "name", () => fileName); newFileName = this.keyword(newFileName, "st", () => new Date().getTime()); newFileName = this.keyword(newFileName, "time", () => { const date = new Date(fs.statSync(filePath).mtime); return `${date.getFullYear()}-${ date.getMonth() + 1 }-${date.getDate()}_${date.getHours()}-${date.getMinutes()}`; }); newFileName += path.extname(filePath); const absNewPath = path.normalize( path.join(path.dirname(filePath), newFileName) ); this.log(`重命名文件: ${filePath} --> ${newFileName}`); fs.renameSync(filePath, absNewPath); } // 文件名关键字替换 keyword( fileName: string, rule: string, variableFn: () => string | number ): string { const key = "{{" + rule + "}}"; const variable = variableFn(); while (fileName.includes(key)) { fileName = fileName.replace(key, String(variable)); } return fileName; } }
执行命令之后的结果都在上面的【命令用法】章节了,可以返回到上面看看输出。
总结
总的来说脚手架这个东西在以后都是非常重要的,因为很多事情都不可能是从零开始,写个脚手架整合一些自己常用的东西,可以很方便的写一些脚本辅助日常工作。
当然,我这篇文章演示的只是冰山一角,还有更多的花样,比如它还能输出表格,选择框,特效,动画,进度条之类的,有很大的探索价值。
到此这篇关于js使用oclif开发命令行工具实现批量修改文件名的文章就介绍到这了,更多相关js批量修改文件名内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!