Node.js脚本集锦

Posted stalendp

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Node.js脚本集锦相关的知识,希望对你有一定的参考价值。

 运行命令行(TODO,日志输出需要改进)

const proc = require('child_process');

var x = function(cmd, showCmd) 
    console.log('>> ' + cmd);
    return new Promise((resolve, reject) => 
        var p = proc.exec(cmd,  maxBuffer: 100 * 1024 * 1024, (err, stdout, stderr) => 
            if(err) 
                console.error(err);
                reject(err);
             else if(stderr) 
                console.error(stderr);                
                reject(stdout);
             else 
                resolve(stdout);
            
        );
    );
;

(async function() 
    await x("ping -t 3 baidu.com");
    var s = await x('ls');

    console.log(s);
)();

 

一个解析数独游戏的程序:

var solverHelper = function(_solver, _type, _sidx) 
    var solver = _solver;
    var type = _type;
    var ess = [];
    let si, sj;
    if(type == 0)  // 方块
        si = Math.floor(_sidx / 3) * 3;
        sj = _sidx % 3 * 3;
        for(let i=0; i<3; i++) 
            for(let j=0; j<3; j++) 
                ess.push(solver.getES(si + i, sj + j));
            
        
     else if(type == 1)  // 行
        si = _sidx;
        sj = 0;
        for(let j=0; j<9; j++) 
            ess.push(solver.getES(si, j));
        
     else if(type==2)  // 列
        si = 0;
        sj = _sidx;
        for(let i=0; i<9; i++) 
            ess.push(solver.getES(i, sj));
        
    

    return 
        updateVal: (val) => 
            for(let i=0; i<9; i++) 
                ess[i].updateVal(val);
            
        ,
        evaluate: () => 
            for(let v=0; v<9; v++) 
                let testV = 1 << v;
                let cnt = 0;
                let ii = 0;
                for(let i=0; i<9; i++) 
                    if((ess[i].Magic & testV) > 0) 
                        cnt ++;
                        ii = i;
                    
                
                if(cnt == 1 && !ess[ii].isOK) 
                    ess[ii].setVal(v + 1);
                
                if(cnt == 0)
                    return false;
            
            return true;
        ,
        printR : () => 
            var rt = [];
            if(type == 0) 
                rt.push(`type: square - ($si, $sj)\\n==========\\n`);
                for(let i=0; i<9; i++) 
                    rt.push(ess[i].Val);
                    rt.push(",");
                    if((i+1)%3 == 0) 
                        rt.push("\\n");
                    
                
             else 
                rt.push(`type: $type==1 ? "row" : "column" - $si,$sj\\n==========\\n`);
                var s = type==1 ? "," : "\\n";
                for(let i=0; i<9; i++) 
                    rt.push(ess[i].Val);
                    rt.push(s);
                
            
            rt.push("\\n");
            console.log(rt.join(""));
        ,
        toString: function() 
            return `$type==0 ? "square" : type==1? "row" : "column" :: ($si, $sj)`;
        
    ;


var elemSolver = function (_solver, _i, _j) 
    var s = _solver;

    var i = _i;
    var j = _j;
    var n = -1;  // 可能个数
    var val;
    var magic;

    return 
        ensureInit : function () 
            if(n<0) 
                val = s.getE(i, j);
                if(val != 0)   // 默认值
                    magic = 1 << (val-1);
                    n = 1;
                    s.notify(this);
                 else 
                    magic = 0x1FF;
                    n = 9;
                
            
        ,
        setVal : function(_val) 
            val = _val;
            magic = 1 << (val-1);
            n = 1;
            s.notify(this);
        ,
        init: function() 
            this.ensureInit();
        ,
        updateVal: function(_val) 
            if(!_val || n == 1)  // 已经完成
                return;

            this.ensureInit();
            magic &= ~(1<<(_val-1));
        ,
        refreshN: function(isInit) 
            if(n == 1) 
                if(isInit) 
                    s.notify(this);
                
                return true;
            

            // 重新计算n
            let vv = 0;
            n = 0;
            for(let x = 0; x < 9; x ++) 
                if((magic & (1<<x)) > 0) 
                    vv = x + 1;
                    n++;
                
            
            if(n==1) 
                val = vv;
                s.notify(this);  // 通知完成
            
            return n > 0;
        ,
        possibleVals : function() 
            var rt = [];
            for(let x = 0; x < 9; x ++) 
                if((magic & (1<<x)) > 0) 
                    rt.push(x+1);
                
            
            return rt;
        ,
        get I() return i,
        get J() return j,
        get N() return n,
        get isOK()  return n == 1;,
        get Val()  return n == 1 ? val : '_',
        get Magic()  return magic; ,
        toString : function() return `($i,$j)_$n_$this.possibleVals().join(",")`;,
        toString2() return `$this.Val.$n==1? "_" : n.$n==1 ? "___" : magic.toString(16).padStart(3, '0')`;,
        serilize: function() 
            return (val & 0xF) | ((n&0xF) << 4) | ((i&0xF)<<8)|((j&0xF)<<12) |((magic & 0x1FF) << 16);
        ,
        deserilize: function(v) 
            val = v&0xF;
            n = (v >> 4) & 0xF;
            i = (v>>8) &0xF;
            j = (v >> 12) & 0xF;
            magic = (v>>16) &0x1FF;
        ,
    ;


var solver = (function()
    var m;
    var ess = [];
    var shs = [];
    var solvedNum = 0;
    var tryQueue = [];

    return 
        _init : function(_m) 
            m = _m;
            for(let i=0; i<9; i++) 
                for (let j=0; j<9; j++) 
                    ess.push(elemSolver(this, i, j));
                
            
            for(let t=0; t<3; t++) 
                let tmp = [];
                for(let i=0; i<9; i++) 
                    tmp.push(solverHelper(this, t, i));
                
                shs.push(tmp);
            

            // 初始化
            for(let i=0; i<81; i++) 
                ess[i].init();
            
            // this.printR(`init => $solvedNum`, true);
        ,
        solve: function(_m) 
            // 重置
            ess = [];
            shs = [];
            solvedNum = 0;
            tryQueue = [];
            // 处理
            this._init(_m);
            if(this._doLogic()) 
                this.printR();
             else 
                console.log("No Result!");
            
            // step 2. do guess
        ,
        doTry : function() 
            // 找到最小范围的
            let smallest = 10;
            let sel;
            for(let i=0; i<81; i++) 
                let tmp = ess[i];
                if(!tmp.isOK) 
                    if(tmp.N < smallest) 
                        smallest = tmp.N;
                        sel = tmp;
                        if(smallest == 2)
                            break;
                    
                
            
            this.saveResult();
            var ps = sel.possibleVals();
            var rt = true;
            for(let i=0; i<ps.length; i++) 
                var v = ps[i];
                this.printR(`Before Try @@ $tryQueue.length - $sel.toString() :: $v `, true);
                sel.setVal(v);
                if(this._doLogic())
                    return true;
                
                this.restoreResult();
            
            this.popResult();
            return false;
        ,
        saveResult: function() 
            var q =[];
            for(let i=0; i<81; i++) 
                q.push(ess[i].serilize());
            
            tryQueue.push(q);
        ,
        restoreResult: function() 
            var q = tryQueue.length > 0 ? tryQueue[tryQueue.length - 1] : undefined;
            solvedNum = 0;
            for(let i=0; i<81; i++) 
                let e = ess[i];
                e.deserilize(q[i]);
                if(e.isOK) 
                    solvedNum++;
                
            

        ,
        popResult: function() 
            tryQueue.pop();
        ,
        _doLogic: function() 
            let tmpNum;
            while(tmpNum != solvedNum && solvedNum < 81) 
                // 1. step
                while(tmpNum != solvedNum && solvedNum < 81) 
                    tmpNum = solvedNum;
                    for(let i=0; i < 81; i++) 
                        if(!ess[i].refreshN()) 
                            console.log(`[Try] 1 Failed at :$ess[i].toString()`);
                            return false;
                        
                    
                
                    
                if(solvedNum < 81) 
                    // 2. step evaluate
                    for(let t=0; t < 3; t++) 
                        for(let i=0; i<9; i++) 
                            if(!shs[t][i].evaluate()) 
                                console.log(`[Try] 2 Failed at : $shs[t][i].toString()`);
                                return false;
                            
                        
                    

                
            

            if(solvedNum!=81) 
                return this.doTry();
             else  
                return true;
            
        ,
        getE: (i, j) => 
            return m[i * 9 + j];
        ,
        getES : (i, j) => 
            return ess[i * 9 + j];
        ,
        notify: (es) => 
            if(es.N != 1)
                return;
            solvedNum ++;
            if(solvedNum < 81) 
                let i = es.I;
                let j = es.J;
                let val = es.Val;
                shs[0][Math.floor(i/3)*3 + Math.floor(j/3)].updateVal(val);
                shs[1][i].updateVal(val);
                shs[2][j].updateVal(val);
             else 
                solvedNum = 81;
            
        ,
        printR : (msg, level)=>
            if(msg) 
                console.log(msg + "\\n");
            
            if(!level) 
                level = 0;
            
            let rt = [`solvedNum: $solvedNum \\n`];
            if(level == 0) 
                for(let i=0; i<9; i++) 
                    for (let j=0; j<9; j++) 
                        rt.push(ess[i*9 + j].Val);
                        rt.push(",");
                        if((j+1)%3 == 0) 
                            rt.push(" ");
                        
                    
                    rt.push("\\n");
                    if((i+1)%3==0) 
                        rt.push("\\n");
                    
                
             else if(level == 1) 
                for(let i=0; i<9; i++) 
                    for (let j=0; j<9; j++) 
                        rt.push(ess[i*9 + j].toString2());
                        rt.push("  ");
                        if((j+1)%3 == 0) 
                            rt.push("        ");
                        
                    
                    rt.push("\\n");
                    if((i+1)%3==0) 
                        rt.push("\\n");
                    
                
            
           
            console.log(rt.join(""));
        ,
        test: function() 
            // this.saveResult();
            // this.restoreResult();
            // this.printR("", true);
        ,
    
)();

solver.solve([
    // 
    3,9,0,  2,0,0,  8,0,0,
    0,0,0,  7,0,0,  0,2,9,
    7,0,0,  3,0,0,  0,5,0,
    // 
    0,0,0,  0,0,0,  9,3,0,
    0,0,0,  4,1,2,  0,0,0,
    0,5,6,  0,0,0,  0,0,0,
    // 
    0,7,0,  0,0,4,  0,0,2,
    4,1,0,  0,0,6,  0,0,0,
    0,0,3,  0,0,7,  0,8,4,
]);

solver.solve([
    // 
    0,0,0,  0,0,0,  0,0,0,
    0,0,0,  0,0,0,  0,0,0,
    0,0,0,  0,0,0,  0,0,0,
    // 
    0,0,0,  0,0,0,  0,0,0,
    0,0,0,  0,0,0,  0,0,0,
    0,0,0,  0,0,0,  0,0,0,
    // 
    0,0,0,  0,0,0,  0,0,0,
    0,0,0,  0,0,0,  0,0,0,
    0,0,0,  0,0,0,  0,0,0,
]);

 

// 用jar的打包方式创建aar文件

var fs = require('fs');
var path = require('path');
const util = require('util');
const exec = util.promisify(require('child_process').exec);

async function jar(fn) 
    var cmd = 'jar cvf ' + fn + ".aar -C " + fn + " " + fn + "/*";
//   const  stdout, stderr  = await exec(cmd);
//   console.log('stdout:', stdout);
//   console.log('stderr:', stderr);
    console.log(cmd);

var dirs = p => fs.readdirSync(p).filter(f=> fs.statSync(path.join(p,f)).isDirectory());
(function() 
    var files = dirs('.');
    files.forEach(function(f)
        if(fs.statSync(f).isDirectory()) 
            var fn = path.basename(f);
            if(fn!="HeroesArena" && fn!="lib_source") 
                // create jar
                jar(fn);
            
        
    );
)();
// 生成Eclipse工程。
// 运行环境,安卓node.js, 并安装node插件:
// npm install unzip-stream --save

var fs = require('fs');
var path = require('path');
var unzip = require('unzip-stream');

var dirs = p => fs.readdirSync(p).filter(f=> fs.statSync(path.join(p,f)).isDirectory());
var basedir = path.join("..", "Assets", "Plugins", "android");
// 一些要处理的aar文件
var aars = ["appcompat-v7-24.1.1", "cardview-v7-24.1.1", "design-24.1.1", "firebase-common-10.2.1", 
        "firebase-iid-10.2.1", "firebase-messaging-10.2.1", "installreferrer-1.0", "play-services-basement-10.2.1",
        "play-services-tasks-10.2.1", "recyclerview-v7-24.1.1", "support-v4-24.1.1", "support-vector-drawable-24.1.1"
];
aars.forEach(function(aarName) 
    var aarFile = path.join(basedir, aarName + ".aar");
    var aarPath = path.join("..", "AndroidBuild", aarName);
    // 解压aar文件到AndroidBuild目录下
    var stream = fs.createReadStream(aarFile).pipe(unzip.Extract( path: aarPath ));
    stream.on("close", function()
        var libPath = path.join(aarPath, "libs");
        var libFile = path.join(aarPath, "classes.jar");
        if(!fs.existsSync(libPath)) 
            fs.mkdirSync(libPath);
        
        // 处理classes.jar文件,改个名字,并移动到libs目录下
        if(fs.existsSync(libFile)) 
            fs.renameSync(libFile, path.join(libPath, aarName + ".jar"));
        
        
        // 为了编译通过,需要创建src目录
        var srcPath = path.join(aarPath, "src");
        if(!fs.existsSync(srcPath)) 
            fs.mkdirSync(srcPath);
        
        
        console.log(aarName);
    );
);

(function() 
    var abp = path.join("..", "AndroidBuild");
    var files = dirs(abp);
    files.forEach(function(f)
        var ff = path.join(abp, f);
        if(fs.statSync(ff).isDirectory()) 
            var fn = path.basename(ff);
            if(fn=="HeroesArena" || fn=="lib_source") 
                var srcPath = path.join(ff, "src");
                if(!fs.existsSync(srcPath)) 
                    fs.mkdirSync(srcPath);
                
            
        
    );
)();

一个日志解析工具

 

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

var DID = 149496940;

var lr = require('readline').createInterface(  // 一行一行读取文件
    input: require('fs').createReadStream('sample.log')
);

//https://stackoverflow.com/questions/30452263/is-there-a-mechanism-to-loop-x-times-in-es6-ecmascript-6-without-mutable-varia
const times = n => f =>   // 循环函数定义,参考下面的调用
    let iter = i => 
      if (i === n) return
      f (i)
      iter (i + 1)
    
    return iter (0)


// 一些正则表达式的使用方法
//182.61.120.11 ha.mobaonline.com - [27/Jan/2018:23:48:30 -0800] "GET /pixel.jpg?client=moba&os=2&type=onWindowFocusChanged_1&is50mClient=1&hd=0&version=1.2.9.184&appVersion=1.2.9&obbVersion=128&channel=googleplay&uuid=ffffffff8b74d89eddf7ae8e0033c587&user_id=14660192&newbie=0&sn=0&f=unity HTTP/1.0" 200 119 "-" "Dalvik/2.1.0 (Linux; U; Android 6.0.1; US699 Build/MMB29M)" "-" "0.229" "-" "-" "-" "182.61.33.150" "182.61.33.150, 113.134.222.207, 113.134.222.207, 182.61.33.150, 182.61.120.11"
var reg = /type=([^&]+).*?user_id=(\\d+)/i;
var regTime = /ReportOnlineTime_(.*)/i;
var regTimeAll =  /(ReportOnlineTime|onWindowFocusChanged_0|OnlineTime|RoomConnected|ProxyConnect|StorageFull|CErrorDLCode|CErrorCheckDstHash|CErrorDL4Times|CErrorDLOpenFile)_.*/i;
var User = function(_id)
    const CNT = 10;
    var id = _id;
    var duration = 0;
    var queue = new Array(CNT);
    var replaced = [];
    var count = 0;

    var fixQueue = function() 
        var tmp = [];
        var start = count > CNT ? count - CNT : 0;
        var n = count > CNT ? 10 : count;
        times(n) (i =>    // 循环函数的调用
            var d = queue[start%CNT];
            tmp.push(d.replace(regTimeAll, "$1"));
            start++;
        );
        queue = tmp;
    ;

    return 
        get ID()   // getter函数
            return id;
        ,
        parse: function(d) 
            var m = regTime.exec(d);
            if(m) 
                var tt = parseInt(m[1]);
                if(duration < tt) 
                    duration = tt;
                
            
            queue[count%CNT] = d;
            count++;
        ,
        analysis: function(us) 
            fixQueue();
            queue.forEach(e => 
                replaced.push(us.getIdx(e));
            );
        ,
        print: function() 
            console.log(id + "->" + replaced.join(","));
        
    ;
;
var cc = 0;
var Users = function() 
    var us = [];
    var dict = ;  // Dictionary的用法
    var dCnt = 0;
    return 
        parse: function(uid, data) 
            var u = us[uid];
            if(u == null) 
                cc++;
                u = new User(uid);
                us[uid] = u;
            
            u.parse(data);
        ,
        getIdx: function(elm) 
            var rt = dict[elm];
            if(rt==null) 
                rt = dCnt;
                dict[elm] = dCnt;
                dCnt++;
            
            return rt;
        ,
        print: function() 
            us.forEach(u => 
                u.analysis(this);
            );

            us.forEach(u => 
                u.print();
            );

            console.log(dict);
        
    ;
;

var DebugUser = function(_uid) 
    var uid = _uid;
    var ds = [];
    return 
        parse : (id, d) => 
            if(id == uid) 
                ds.push(d);
            
        ,
        print : v => 
            console.log("================== " + uid + " ==============");
            ds.forEach(elm => 
               // console.log(elm);
            );
        
    ;
;

//======================= MAIN Start =========================
var du = new DebugUser(DID);
var us = new Users();
var t0 = new Date().getTime();
lr.on('line', line => 
    var m = reg.exec(line);
    if(m) 
        var id = m[2];
        var dd = m[1];
        us.parse(id, dd);
        du.parse(id, dd);
    
).on('close', v => 
    us.print();
    du.print();
    var t1 = new Date().getTime();
    console.log("Finished by " + ((t1 - t0)/1000.0) + " seconds.")  // 计算运行时间
);

//======================= MAIN End =========================

处理ios的崩溃日志的工具,原理参考 Understanding and Analyzing Application Crash Reports

其实就是atos工具的使用,目前添加了对文件的处理。输入是 heroesarena.app.dSYM和crash.log,输出是crash_parsed.log

#!/usr/bin/env node
var fs = require('fs');  
var path = require('path');  
var stream = require('stream');
// https://github.com/abbr/deasync
// npm install deasync
var deasync = require('deasync'); 
var cp = require('child_process');  
const es = require('event-stream');

var cmdPre = "atos -arch arm64 -o heroesarena.app.dSYM/Contents/Resources/DWARF/heroesarena -l";
var reg = /heroesarena\\s+(0x[^\\s]+)\\s+(0x[^\\s]+)/i;
var lr = require('readline').createInterface(
    input: fs.createReadStream('crash.log')
);

var exec = deasync(cp.exec);
//0   heroesarena                         0x0000000100ed3514 0x100040000 + 15283476
var reg2 = /^\\d+\\s+heroesarena\\s+((0x[^\\s]+)\\s+(0x[^\\s]+).*)$/i;
var reg3 = /(0x[^\\s]+\\s+0x[^\\s]+.*$)/i;
var parse = function(dict)   // convert the file
    fs.createReadStream('crash.log')
        .pipe(es.split())
        .pipe(es.mapSync(l => 
            var m = reg2.exec(l);
            if(m) 
                var t1 = dict[m[3]];

                if(t1!=null) 
                    var t2 = t1[m[2]];
                    if(t2!=null) 
                        l = l.replace(reg3, t2);
                    
                
            
            return l;
        ))
        .pipe(es.join('\\n'))
        .pipe(fs.createWriteStream('crash_parsed.log'))
        .on('close', () => 
            console.log('Done!');
        );
;

var dict = [];
lr.on('line', line => 
    var m = reg.exec(line);
    if(m) 
        var addr1 = m[2];
        var offsets = dict[addr1];
        if(offsets == null) 
            offsets = [];
            dict[addr1] = offsets;
        
        
        var addr2 = m[1];
        if(offsets[addr2] == null) 
            offsets[addr2] = addr2;            
        
    
).on('close', v => 
    Object.keys(dict).forEach(adr1 => 
        var adr2s = dict[adr1];
        var keys = Object.keys(adr2s).map(x => x);
        var rst = exec(`$cmdPre $adr1 $keys.join(' ')`);  // 这里的写法,类似于stringFormat
        var lines  = rst.split(/\\r?\\n/);
        
        for(var i=0; i<keys.length; i++) 
            adr2s[keys[i]] = lines[i];
        
        parse(dict);
    );
);
#!/usr/bin/env node  
var fs = require('fs');    
var path = require('path');    
var stream = require('stream');  
var crypto = require('crypto');

var projDir = "D:\\\\_Moba\\\\Working\\\\1.7";  // 设置工程文件夹!!

var baseDir = path.join(projDir, "\\\\Assets\\\\BuildOnlyAssets");

var okFiles = ;
var okFile2 = ;
var md5 = str => crypto.createHash('md5').update(str).digest('hex'); // MD5相关算法
var tmpDirs = [];
var reg = /([^\\.]+)\\..+$/i;
var reg2 = /(?:[^\\\\/]+[\\\\/])*(([^\\.]+)(\\..+)?)$/gi;
// 遍历文件夹,并计算MD5
var myIter = function(cur, dirs) 
   // console.log(cur);
    var full = path.join(baseDir, cur);
    fs.readdirSync(full).forEach(f => 
        if(!f.startsWith(".")) 
            var tmp = path.join(cur, f);
            if(fs.statSync(path.join(baseDir, tmp)).isDirectory()) 
                dirs.push(tmp);
             else   // 计算MD5
                if(!f.endsWith(".meta") ) 
                    var fn = `SuI9_hero_project_2014/$tmp.toLowerCase().replace(/\\\\/gi, "/").replace(reg, "$1").assets`;
                    var m = md5(fn);  // MD5的用法
                    okFiles[m] = tmp;
                    okFile2[tmp.replace(reg2, "$1")] = m;
                
            
        
    );


tmpDirs.push(".");
while(tmpDirs.length > 0)   // 处理所有的文件
    myIter(tmpDirs.shift(), tmpDirs); // queue的用法


// 把文件大小,显示成合适的大小
var fmtSize = function(size)   // 格式化文件大小的显示
    var tn = ['B', 'K', 'M', 'G', 'T'];
    var t = 0;
    while(size > 1024) 
        size /= 1024;
        t++;
    
    return `$size.toFixed(2)$tn[t]`;  // float保留两位小数


var jsonfile = "fileList4.json";
if(fs.existsSync(jsonfile))   // 打印一些下载包大小
    var lr = require('readline').createInterface(  // 一行一行读取文件  
        input: require('fs').createReadStream(jsonfile)  
    );  
    var reg = /"f":"(\\d+)".+"o":(\\d)/i;
    var size1=0, size2=0;
    lr.on("line", line => 
        var m = reg.exec(line);
        if(m) 
            if(m[2]==1) 
                size2 += parseInt(m[1]); // 把字符串转化为int
             else 
                size1 += parseInt(m[1]);
                        
         else 
         //   console.log(line);
        
    ).on("close", line => 
        console.log(`required_Size: $fmtSize(size1), optional_Size: $fmtSize(size2)`);
    );


console.log("输入查询的文件:");

var  rl = require('readline').createInterface(
    input:process.stdin,
    output:process.stdout
);

rl.on('line', function(line)
    if(line.length<=0)
        return;

    if(line.startsWith(">>")) 
        var reg = />>\\s*([^\\.]+)(?:\\.(.*))?$/gi;
        var fn =  line.toLowerCase().replace(/\\\\/gi, "/");
        var m = (reg).exec(fn);
        if(m[2])   // 有后缀
            if(/(?:bnk)|(?:wen)|(?:ddx)|(?:ddv)|(?:txt)/gi.test(m[2])) 
                fn = fn.replace(reg, "SuI9_hero_project_2014/$1.$2")
             else 
                fn = fn.replace(reg, "SuI9_hero_project_2014/$1.assets");
            
         else  
            fn = fn.replace(reg, "SuI9_hero_project_2014/$1.assets");
        
        var m = md5(fn);
        console.log(`$fn => $m`);
     else 
        var dict = okFiles;
        var reg = /(?:[^\\\\/]+[\\\\/])*(([^\\.]+)(\\..+)?)$/gi;
        var m = reg.exec(line);
        if(!m)
            return;
    
        if(!m[3] || m[3] == ".ddx") 
            dict = okFiles;
            line = m[2];
         else 
            dict = okFile2;
            line = m[1];
        
       
        // console.log(nn);
        var realName = dict[line];
        if(realName) 
            console.log(realName);
         else 
            console.log("Not found! ");
        
    
    console.log();
);
rl.on('close', function() 
    console.log('bye bye');
    process.exit(0);
);

// 一些测试
// var lr = require('readline').createInterface(  
//     input: fs.createReadStream('patch.json')  
// );  

// var reg = /".":"(.\\/[^\\"]+)"/i; 
// var dict = [];  
// lr.on('line', line =>     // 
//     var m = reg.exec(line);  
//     if(m)   
//         var fn = m[1];
//         var realName = okFiles[fn];
//         if(!realName) 
//             console.log("not found ==> " + fn);
//          else 
//             console.log(realName);
//         
//       
// ).on('close', v =>   
//     console.log("Done!!");
// );  

 

通过adb shell列出文件内容

#!/usr/bin/env node  
var fs = require('fs');    
var path = require('path');    

function exec(cmd, parameter, callback) 
    var proc = require('child_process').exec(cmd);
    var content = "";
    proc.stdout.setEncoding('utf8');
    proc.stdout.on('data', function (chunk) 
        content += chunk;
    );
    proc.stdout.on('end', function () 
        callback(content);
    );
    proc.stdin.write(parameter);


exec("adb shell", "cd /sdcard/Android/data/com.ucool.heroesarena/patch6  && find . -type f \\\\( -name '*.ddx' -o -name '*.bnk' \\\\)  -print0 | xargs -0 ls -al && exit \\r\\n", str => 
    console.log(str);
);
#!/usr/bin/env node  
var fs = require('fs');    
var path = require('path');    
var proc = require('child_process');

var baseDir = "D:\\\\_Moba\\\\Working\\\\client_1.5";
baseDir = path.join(baseDir, "Assets\\\\BuildOnlyAssets");

// Promise的用法参考 http://exploringjs.com/es6/ch_promises.html
var exec = function(cmd) 
    return new Promise((resolve, reject) => 
        var p = proc.exec(cmd,  maxBuffer: 100 * 1024 * 1024, (err, stdout, stderr) => 
            if(err) 
                reject(err);
             else 
                resolve(stdout);
            
        );
    );


var jsonName = "fileList4.json";
var delJson = function() 
    if(fs.existsSync(jsonName)) 
        fs.unlinkSync(jsonName);
       
;

 // "a":"0/013952985da37eff54db7669b280106b.ddx","b":"f1698cba18bc707705f48d96659e5bc7","c":"13213","d":"1.0.84.1077","e":"1",
 // "f":"6968","g":"ad3283ca38a64955083e8bf7746f6305","h":"1","t":1,"o":0,
var FileInfo = function(str) 
    var info;
    try 
        info = JSON.parse(str.replace(/([^]+),?/, "$1"));
     catch(e) 
    
    var isHit = false;
    var fullname = null;
    return 
        get IsValid()    return info && info.a && info.b; ,
        get filename()   return info.a; ,
        get hash()       return info.b; ,
        get size()       return info.c; ,
        get dlSubFolder()        return info.d; ,
        get dlSuccess()          return info.e; ,
        get downloadSize()       return info.f; ,
        get downloadHash()       return info.g; ,
        get autoUncompress()     return info.h; ,
        get optional()           return info.o; ,
        get fileType()           return info.t; ,
        
        get IsHint()  return isHit ;,
        markHit : function ()  isHit = true; ,
        get Fullname() 
            if(fullname == null) 
                if(okFiles) 
                    var reg = /.\\/([^\\.]+)\\.ddx/;
                    if(reg.test(this.filename)) 
                        fullname = okFiles[this.filename.replace(reg, "$1")];
                    
                
                if(fullname==null) 
                    fullname = "-";
                
            
            return fullname;
        ,
        get desc() 
            return `$this.filename : $this.Fullname : $this.optional ? "optional" : "required"`;
        
    ;


var dict = ;
var okFiles = ;
var md5 = str => require('crypto').createHash('md5').update(str).digest('hex'); // MD5相关算法

var tmpDirs = [];
tmpDirs.push(".");

// 遍历文件夹,并计算MD5
var myIter = function(cur) 
    // console.log(cur);
    var full = path.join(baseDir, cur);
    fs.readdirSync(full).forEach(f => 
        if(!f.startsWith(".")) 
            var tmp = path.join(cur, f);
            if(fs.statSync(path.join(baseDir, tmp)).isDirectory()) 
                tmpDirs.push(tmp);
             else   // 计算MD5
                if(!f.endsWith(".meta") ) 
                    var fn = `SuI9_hero_project_2014/$tmp.toLowerCase().replace(/\\\\/gi, "/").replace(/([^\\.]+)\\..+$/, "$1").assets`;
                    var m = md5(fn);  // MD5的用法
                    okFiles[m] = tmp;
                
            
        
    );


var readDirs = new Promise((resolve, reject) =>  // 读取本地文件,并形成字典
    while(tmpDirs.length > 0)   // 处理所有的文件
        myIter(tmpDirs.shift()); // queue的用法
    
    resolve();
); 

readDirs.then(r=> 
    exec('adb pull /sdcard/Android/data/com.ucool.heroesarena/fileList4.json')  // 拉取fileList4.json
).then(r =>     // 解析文件
    return new Promise((resolve, reject) =>  
        if(!fs.existsSync(jsonName)) 
            return reject();
         
        var lr = require('readline').createInterface(  
            input: fs.createReadStream(jsonName)  
        );  
       
        lr.on('line', line =>  
            var info = new FileInfo(line);
            if(info.IsValid) 
                dict[info.filename] = info;
            
        ).on('close', v =>   
            resolve();
        );  
    );
).then(r =>   // 列出手机上相应目录下的文件名
    return exec('adb shell "cd /sdcard/Android/data/com.ucool.heroesarena/patch6 && find . -type f \\\\( -name \\"*.ddx\\" -o -name \\"*.bnk\\" \\\\)  -print0 | xargs -0 ls -al"');
).then(r =>   // 尝试对比,是否有文件缺失
    return new Promise((resolve, reject) => 
        //-rw-rw---- 1 u0_a260 sdcard_rw   85794 2018-03-21 14:45 ./c/cf9da209844daa8db78dd4140e000c34.ddx
        var reg = /(?:\\S+\\s+)4(\\d+)\\s+(?:(?:\\S+\\s+)2)\\.\\/([^\\r\\n]+)/g;
        // 全局文本搜索 https://stackoverflow.com/questions/1222045/how-to-loop-all-the-elements-that-match-the-regex
        var m;
        
        while((m = reg.exec(r)) !== null) 
            
            var f = dict[m[2]];
            if(f) 
                if(m[2].startsWith("Audio")) 
                //    console.log(m[2]);
                
                f.markHit();
             else 
                console.log(`$f is not exists in fileList4.json!`);
            
        
        
        resolve();
    );
).then(r =>  // 打印结果
    Object.keys(dict).forEach(key => 
        var f = dict[key];
        if(!f.IsHint) 
           console.log(`NOT FOUND:: $f.desc`);
        
    );
    console.log("============== Run Finished!!==================");
   // delJson();
) .catch(r => 
    console.log(`Error: $r`);
   // delJson();
);

 

一个词典:

 

var fs = require('fs');  

var lr = require('readline').createInterface(    
    input: fs.createReadStream('words1M.csv')    
);    

var pageSize = 30;

var pattern = process.argv[2].replace(/(\\*)/g, "\\.$1").replace(/(\\?)/g, "\\.$1"); 
var page = parseInt(process.argv[3]) || 0;

var skip = page * pageSize;
re = new RegExp(`^$pattern$`); // /^.*acro.*$/i;
var count = 0, lc = 0;
lr.on('line', line =>    
    lc++;
    if(re.test(line)) 
        count++;
        if(count > skip && (count - skip) <= pageSize) 
            console.log(`$("" + count).padEnd(5)$line.padEnd(20)$("" + (lc/10000).toFixed(4)).padStart(8)`);
        
    
).on('close', v =>     
    console.log('---------------------------------------');
    console.log(`$pattern   page: $page/$parseInt(count/pageSize)  total: $count`);
);    

一个单词查询工具

var fs = require('fs');
const readline = require('readline');

var lr = readline.createInterface(
    input: fs.createReadStream('words1M.csv')
);

var dict = 
var init = function(total) 
    var acc = total / 10, acc_ = 0;
    process.stdout.write('Loading');
    return new Promise((resolve, reject) => 
        var lc = 0;
        lr.on('line', line => 
            lc++;
            if (lc > total)
                return;
            var w = line;
            var next = dict;
            for (var j = 0; j < w.length; j++) 
                var c = w.charAt(j);
                if (next[c] == null) 
                    next[c] = ;
                
                next = next[c];
            
            if (next) 
                if (next['@'] == null) 
                    next['@'] = lc;
                 else 
                    //    console.warn("has number!");
                
            
            if(++acc_ > acc) 
                acc_ = 0;
                process.stdout.write('.');
            
        ).on('close', v => 
            resolve();
        );
    );
;
var search = w => 
    var next = dict;
    for (var i = 0; i < w.length; i++) 
        var c = w.charAt(i);
        if (next[c] != null) 
            next = next[c];
         else 
            next = null;
            break;
        
    
    return next && next['@'] || -1;


const rl = readline.createInterface(
    input: process.stdin,
    output: process.stdout
);

var query = function() 
    return new Promise((resolve, reject) =>  
        rl.question('> ', w => 
            if(w.length == 0) 
                resolve();
                return;
            
            var ss = w.split(',');
            var rt = [];
            for(var s of ss) 
                s = s.trim().toLowerCase();
                var idx = search(s);
                if(idx > 0) 
                    rt.push([s, idx]);
                
            
            rt.sort((lhs, rhs) => lhs[1] - rhs[1]);
            var l1 = "", l2 = "", ls = "";
            for(var s of rt) 
                var wl = s[0].length;
                var ll = 15;
                while(ll<=wl) 
                    ll += 15;
                
                l1 += s[0].padEnd(ll);
                ls += "".padEnd(ll, '-');
                l2 += s[1].toString().padEnd(ll);
            
            resolve(`$l2\\r\\n$ls\\r\\n$l1\\r\\n\\r\\n`);
        );
    );
;

(async function() 
    await init(800000);
    while(true) 
        var result = await query();
        if(result) 
            console.log(`$result`);
         
    
)();

 

1. 介绍Java面向对象,很好的书籍:

 

《The principles of Object-Oriented javascript》 by Nicholas C. Zakas

2. 介绍Node.js很好的书籍(目前感觉Stream和pipe方面的介绍非常ok):

《Node.js Design Patterns》by Mario Casciaro

 

 

 

以上是关于Node.js脚本集锦的主要内容,如果未能解决你的问题,请参考以下文章

node.js调试

用node写一个皖水公寓自动刷房源脚本

如何将 Node.js 设置为始终在服务器(如 Apache)上运行 [重复]

如何从主 node.js 脚本运行多个 node.js 脚本?

node.js,捕捉错误所以脚本不会中断?

我开始讨厌node.js了