yo!使用javascript写shell脚本 一

5,432 阅读2分钟

这是我参与8月更文挑战的第5天,活动详情查看:8月更文挑战

本文主要总结一下使用nodejs写脚本的流程及一些常见场景。

一般来说,我们都是用shell写脚本的,但是shell的语法比较难记,也不太好用,所以推荐前端程序员使用javascript来写脚本。

注意,执行脚本的前提是电脑安装了node环境。

最简单的脚本

在编辑器中输入以下内容:

#!/usr/bin/env node
console.log('hello world');

保存为test,执行该脚本 node test,然后可以在控制台获得输出。

更进一步,我们给该脚本一个执行权限,

chmod 755 test

然后就可以通过 ./test 执行该脚本了

例子-读取给定文件夹下所有的文件

读取当前文件夹使用 fs.readdirSync方法,该方法会返回一个数组,包含了给定文件夹下的所有子文件夹或文件,

举个栗子,在当前目录我有个test文件夹

test
├── 1.html
├── 1.txt
└── files

fs.readdirSync('./test') 的输出为 [ '1.html', '1.txt', 'files' ]

新建个文件,getFile,用来存放脚本代码

写死的文件夹

读取给定目录下所有文件并输出的代码如下:

#!/usr/bin/env node

const testFolder = './test/';
const fs = require('fs');

fs.readdirSync(testFolder).forEach(file => {
  console.log(file);
});

获取用户输入

以上代码的给定的路径是写死的,我们需要作为参数输入,nodejs读取用户输入的方法:

const [nodeEnv,dir,...args]=process.argv //args是用户输入的参数

修改脚本代码:

#!/usr/bin/env node

const fs = require('fs');
const [nodeEnv,dir,...args]=process.argv

// 获取用户输入的路径
const folder=args[0]

fs.readdirSync(folder).forEach(file => {
  console.log(file);
});

现在执行脚本时,路径就可以自己输入了

node getFile 你的路径 

递归读取

以上代码只能读取一层,对于文件夹下有子文件夹的情况不能处理,所以为了处理子文件夹,改成递归读取

递归读取的方法如下:

function walkSync(currentDirPath, callback) {
    fs.readdirSync(currentDirPath).forEach(function (name) {
        var filePath = path.join(currentDirPath, name);
        var stat = fs.statSync(filePath);
        if (stat.isFile()) {
            callback(filePath, stat);
        } else if (stat.isDirectory()) {
            walkSync(filePath, callback);
        }
    });
}

原理是使用fs.readdirSync读取给定目录,获取一个数组,遍历数组,如果数组中有文件夹,递归读取,以上方法接收一个callback,用于对每个文件进行处理

getFile 修改后的代码如下:

#!/usr/bin/env node

const fs = require('fs');
const path=require('path')


function walkSync(currentDirPath, callback) {
    fs.readdirSync(currentDirPath).forEach(function (name) {
        var filePath = path.join(currentDirPath, name);
        var stat = fs.statSync(filePath);
        if (stat.isFile()) {
            callback(filePath, stat);
        } else if (stat.isDirectory()) {
            walkSync(filePath, callback);
        }
    });
}
;(function(){
    const [nodeEnv,dir,...args]=process.argv
    // 获取用户输入的路径
    const folder=args[0]
    walkSync(folder,(filePath,stat)=>{
        // 在这里对文件进行处理,filePath是文件路径,stat是文件的信息
    })
}())

有了文件的列表,我们就能做很多事情了,例如:

  • 文件批量重命名、批量移动
  • 图片批量压缩
  • 视频、音频批量转换编码格式

不过以上功能需要借助其他的第三方库实现,下篇文章做具体讲解。