今天项目遇到了一个批量重命名某个目录下所有文件的需求,发现大家处理的方式完全不一样:
普通工程师
在 Mac 下批量重命名文件是非常方便的,只要批量选择所有文件,右键「重新命名」就会弹出来一个输入框,选择匹配规则,然后输入替换文字即可,例如将 1.jpeg
~ 3.jpeg
的后缀全改成 .png
,就可以这么操作:
那如果想递归更改某个目录下所有指定后缀的文件该如何操作呢?例如:把 src 目录下所有 .ts
后缀文件都改成 .js
,这种方式就无能为力了。
高级工程师
先安装 rename
,然后一行代码搞定:
brew install rename
find . -type f -name "*.ts" -print | xargs rename 's/\.ts/\.js/'
如果只是想查看替换效果,不真正替换的话,可以添加 -n
参数,例如:
$ find . -type f -name "*.ts" -print | xargs rename -n 's/\.ts/\.js/'
'./order.class.ts' would be renamed to './order.class.js'
'./order.service.ts' would be renamed to './order.service.js'
'./order.hooks.ts' would be renamed to './order.hooks.js'
资深工程师
那如果还有更复杂的规则,只能写脚本了,可以用任何语言例如 nodejs、python、java、go 等。例如用 node.js 写一个 rename 函数,把指定文件夹下面所有文件或文件夹都加上一个前缀,代码如下:
const fs = require("fs")
const path = require('path')
function rename(dir, prefix = 'rename_') {
fs.readdir(dir, (e, files) => {
for (let i = 0; i < files.length; i++) {
let f = files[i]
fs.rename(path.join(dir, f), path.join(dir, prefix + f), (err) => {
if (err) throw err
console.log(f + ' --> ' + prefix + f)
})
}
})
}
rename(__dirname)
不过这个例子还是太简单了,对于复杂重命名的需求,就要用到之前讲过的 glob 语法了,例如想找到 src 目录下所有 js 和 jsx 文件,3 行代码搞定:
const glob = require('glob')
const files = glob.sync('src/**/*.js{,x}')
console.log(files)
既然拿到了文件的绝对路径,接下来就简单了,直接调用 fs.rename
方法替换成你想要的名称即可。不过建议大家在重命名的时候,配合 Git 一起使用,一旦出现错误能够及时发现并回滚:
git checkout . && git clean -xdf