博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Nodejs 进阶:readline 实现日志分析 + 简易命令行工具
阅读量:6079 次
发布时间:2019-06-20

本文共 5486 字,大约阅读时间需要 18 分钟。

本文摘录自《Nodejs学习笔记》,更多章节及更新,请访问 。欢迎加群交流,群号 。

模块概览

readline是个非常实用的模块。如名字所示,主要用来实现逐行读取,比如读取用户输入,或者读取文件内容。常见使用场景有下面几种,本文会逐一举例说明。本文相关代码可在笔者上找到。

  • 文件逐行读取:比如说进行日志分析。
  • 自动完成:比如输入npm,自动提示"help init install"。
  • 命令行工具:比如npm init这种问答式的脚手架工具。

基础例子

先看个简单的例子,要求用户输入一个单词,然后自动转成大写

const readline = require('readline');const rl = readline.createInterface({    input: process.stdin,    output: process.stdout});rl.question('Please input a word: ', function(answer){    console.log('You have entered {%s}', answer.toUpperCase());    rl.close();});复制代码

运行如下:

➜  toUpperCase git:(master) ✗ node app.js Please input a word: helloYou have entered {HELLO}复制代码

例子:文件逐行读取:日志分析

比如我们有如下日志文件access.log,我们想要提取“访问时间+访问地址”,借助readline可以很方便的完成日志分析的工作。

[2016-12-09 13:56:48.407] [INFO] access - ::ffff:127.0.0.1 - - "GET /oc/v/account/user.html HTTP/1.1" 200 213125 "http://www.example.com/oc/v/account/login.html" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.98 Safari/537.36"[2016-12-09 14:00:10.618] [INFO] access - ::ffff:127.0.0.1 - - "GET /oc/v/contract/underlying.html HTTP/1.1" 200 216376 "http://www.example.com/oc/v/account/user.html" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.98 Safari/537.36"[2016-12-09 14:00:34.200] [INFO] access - ::ffff:127.0.0.1 - - "GET /oc/v/contract/underlying.html HTTP/1.1" 200 216376 "http://www.example.com/oc/v/account/user.html" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.98 Safari/537.36"复制代码

代码如下:

const readline = require('readline');const fs = require('fs');const rl = readline.createInterface({    input: fs.createReadStream('./access.log')});rl.on('line', (line) => {    const arr = line.split(' ');     console.log('访问时间:%s %s,访问地址:%s', arr[0], arr[1], arr[13]);});复制代码

运行结果如下:

➜  lineByLineFromFile git:(master) ✗ node app.js访问时间:[2016-12-09 13:56:48.407],访问地址:"http://www.example.com/oc/v/account/login.html"访问时间:[2016-12-09 14:00:10.618],访问地址:"http://www.example.com/oc/v/account/user.html"访问时间:[2016-12-09 14:00:34.200],访问地址:"http://www.example.com/oc/v/account/user.html"复制代码

例子:自动完成:代码提示

这里我们实现一个简单的自动完成功能,当用户输入npm时,按tab键,自动提示用户可选的子命令,如help、init、install。

  • 输入np,按下tab:自动补全为npm
  • 输入npm in,按下tab:自动提示可选子命令 init、install
  • 输入npm inst,按下tab:自动补全为 npm install
const readline = require('readline');const fs = require('fs');function completer(line) {    const command = 'npm';    const subCommands = ['help', 'init', 'install'];    // 输入为空,或者为npm的一部分,则tab补全为npm    if(line.length < command.length){        return [command.indexOf(line) === 0 ? [command] : [], line];    }    // 输入 npm,tab提示 help init install    // 输入 npm in,tab提示 init install    let hits = subCommands.filter(function(subCommand){         const lineTrippedCommand = line.replace(command, '').trim();        return lineTrippedCommand && subCommand.indexOf( lineTrippedCommand ) === 0;    })    if(hits.length === 1){        hits = hits.map(function(hit){            return [command, hit].join(' ');        });    }    return [hits.length ? hits : subCommands, line];}const rl = readline.createInterface({  input: process.stdin,  output: process.stdout,  completer: completer});rl.prompt();复制代码

代码运行效果如下,当输入npm in,按下tab键,则会自动提示可选子命令init、install。

➜  autoComplete git:(master) ✗ node app.js> npm ininit     install复制代码

例子:命令行工具:npmt init

下面借助readline实现一个迷你版的npm init功能,运行脚本时,会依次要求用户输入name、version、author属性(其他略过)。

这里用到的是rl.question(msg, cbk)这个方法,它会在控制台输入一行提示,当用户完成输入,敲击回车,cbk就会被调用,并把用户输入作为参数传入。

const readline = require('readline');const fs = require('fs');const rl = readline.createInterface({    input: process.stdin,    output: process.stdout,    prompt: 'OHAI> '});const preHint = `This utility will walk you through creating a package.json file.It only covers the most common items, and tries to guess sensible defaults.See \`npm help json\` for definitive documentation on these fieldsand exactly what they do.Use \`npm install 
--save\` afterwards to install a package andsave it as a dependency in the package.json file.Press ^C at any time to quit.`;console.log(preHint);// 问题let questions = [ 'name', 'version', 'author'];// 默认答案let defaultAnswers = [ 'name', '1.0.0', 'none' ];// 用户答案let answers = [];let index = 0;function createPackageJson(){ var map = {}; questions.forEach(function(question, index){ map[question] = answers[index]; }); fs.writeFileSync('./package.json', JSON.stringify(map, null, 4));}function runQuestionLoop() { if(index === questions.length) { createPackageJson(); rl.close(); return; } let defaultAnswer = defaultAnswers[index]; let question = questions[index] + ': (' + defaultAnswer +') '; rl.question(question, function(answer){ answers.push(answer || defaultAnswer); index++; runQuestionLoop(); });}runQuestionLoop();复制代码

运行效果如下,最后还像模像样的生成了package.json(害羞脸)。

➜  commandLine git:(master) ✗ node app.jsThis utility will walk you through creating a package.json file.It only covers the most common items, and tries to guess sensible defaults.See `npm help json` for definitive documentation on these fieldsand exactly what they do.Use `npm install 
--save` afterwards to install a package andsave it as a dependency in the package.json file.Press ^C at any time to quit.name: (name) helloversion: (1.0.0) 0.0.1author: (none) chyingp复制代码

写在后面

有不少基于readline的有趣的工具,比如各种脚手架工具。限于篇幅不展开,感兴趣的同学可以研究下。

相关链接

转载地址:http://hhhgx.baihongyu.com/

你可能感兴趣的文章
aaa
查看>>
批处理命令篇--配置免安装mysql
查看>>
VMWare虚拟机系统网络配置
查看>>
性能优化你必须知道的那些事儿
查看>>
锋利的jQuery-4--给事件添加命名空间
查看>>
linux概念之cpu分析
查看>>
性能调优攻略
查看>>
Java策略模式(Strategy模式) 之体验
查看>>
负载均衡探测器lbd
查看>>
【转】浅谈.net remoting 与webservice
查看>>
Golang 笔记 5 go语句
查看>>
ef core
查看>>
JavaScript——DOM或以树形展示的Web页面
查看>>
Linux之用户管理--初级上
查看>>
使用Chrome快速实现数据的抓取(一)——概述
查看>>
数据库原理及应用第7章课后习题答案
查看>>
开始前的准备
查看>>
LeetCode(30) Substring with Concatenation of All Words
查看>>
互联网广告思维导图,各种名称解释看这篇就够了
查看>>
SQL索引一步到位
查看>>