模块概览

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: hello
You 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 in
init 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 fields
and exactly what they do. Use \`npm install <pkg> --save\` afterwards to install a package and
save 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.js

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 fields
and exactly what they do. Use `npm install <pkg> --save` afterwards to install a package and
save it as a dependency in the package.json file. Press ^C at any time to quit. name: (name) hello
version: (1.0.0) 0.0.1
author: (none) chyingp

写在后面

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

相关链接

https://nodejs.org/api/readline.html

NodeJS学习笔记 (25)逐行读取-readline(ok)的更多相关文章

  1. Nodejs学习笔记(十六)--- Pomelo介绍&入门

    目录 前言&介绍 安装Pomelo 创建项目并启动 创建项目 项目结构说明 启动 测试连接 聊天服务器 新建gate和chat服务器 配置master.json 配置servers.json ...

  2. Nodejs学习笔记(十六)—Pomelo介绍&入门

    前言&介绍 Pomelo:一个快速.可扩展.Node.js分布式游戏服务器框架 从三四年前接触Node.js开始就接触到了Pomelo,从Pomelo最初的版本到现在,总的来说网易出品还算不错 ...

  3. Nodejs学习笔记(四)——支持Mongodb

    前言:回顾前面零零碎碎写的三篇挂着Nodejs学习笔记的文章,着实有点名不副实,当然,这篇可能还是要继续走着离主线越走越远的路子,从简短的介绍什么是Nodejs,到如何寻找一个可以调试的Nodejs ...

  4. Nodejs学习笔记(三)——一张图看懂Nodejs建站

    前言:一条线,竖着放,如果做不到精进至深,那就旋转90°,至少也图个幅度宽广. 通俗解释上面的胡言乱语:还没学会爬,就学起走了?! 继上篇<Nodejs学习笔记(二)——Eclipse中运行调试 ...

  5. Nodejs学习笔记(二)——Eclipse中运行调试Nodejs

    前篇<Nodejs学习笔记(一)——初识Nodejs>主要介绍了在搭建node环境过程中遇到的小问题以及搭建Eclipse开发Node环境的前提步骤.本篇主要介绍如何在Eclipse中运行 ...

  6. IOS学习笔记25—HTTP操作之ASIHTTPRequest

    IOS学习笔记25—HTTP操作之ASIHTTPRequest 分类: iOS2012-08-12 10:04 7734人阅读 评论(3) 收藏 举报 iosios5网络wrapper框架新浪微博 A ...

  7. NodeJS学习笔记之Connect中间件模块(一)

    NodeJS学习笔记之Connect中间件模块(一) http://www.jb51.net/article/60430.htm NodeJS学习笔记之Connect中间件模块(二) http://w ...

  8. Nodejs学习笔记(六)--- Node.js + Express 构建网站预备知识

    目录 前言 新建express项目并自定义路由规则 如何提取页面中的公共部分? 如何提交表单并接收参数? GET 方式 POST 方式 如何字符串加密? 如何使用session? 如何使用cookie ...

  9. Nodejs学习笔记(十五)--- Node.js + Koa2 构建网站简单示例

    目录 前言 搭建项目及其它准备工作 创建数据库 创建Koa2项目 安装项目其它需要包 清除冗余文件并重新规划项目目录 配置文件 规划示例路由,并新建相关文件 实现数据访问和业务逻辑相关方法 编写mys ...

随机推荐

  1. 几个常用ORACLE运维监控的SQL语句

    1.消耗CPUSELECT a.CPU_TIME, --CPU时间 百万分之一(微秒)              a.OPTIMIZER_MODE,--优化方式              a.EXEC ...

  2. Gram矩阵 迁移学习 one-shot 之类

    格拉姆矩阵是由内积空间中的向量两两内积而得.格拉姆矩阵在向量为随机的情况下也是协方差矩阵.每个数字都来自于一个特定滤波器在特定位置的卷积,因此每个数字代表一个特征的强度,而Gram计算的实际上是两两特 ...

  3. LeetCode 744. Find Smallest Letter Greater Than Target (时间复杂度O(n))

    题目 太简单了,直接上代码: class Solution { public: char nextGreatestLetter(vector<char>& letters, cha ...

  4. swift语言点评十四-继承

    Overriding A subclass can provide its own custom implementation of an instance method, type method, ...

  5. 待解决问题 oc

    读书破万卷 Associated Object hash实现 Dynamic Method Resolution Message Forwarding forwardingTargetForSelec ...

  6. Golang 中的 面向对象: 方法, 类, 方法继承, 接口, 多态的简单描述与实现

    前言: Golang 相似与C语言, 基础语法与C基本一致,除了广受争议的 左花括号 必须与代码同行的问题, 别的基本差不多; 学会了C, 基本上万变不离其宗, 现在的高级语言身上都能看到C的影子; ...

  7. oracle查询之null值转化

    函数coalesce(c1,c2,c3......cn);返回第一个不为null的值

  8. Django学习之配置篇

    MTV Model Template View 数据库 模版文件 业务处理 了解Django框架,功能齐全 一.安装Django&Django基本配置 安装Django pip3 django ...

  9. bytes、str与unicode

    1.Python3字符序列的类型 bytes -> 原始的8位值(既字节) str -> Unicode字符 2.Python2字符序列的类型 str -> 原始的8位值(既字节) ...

  10. Multi-Byte Character Set & Unicode Character Set

    本系列文章由 @YhL_Leo 出品,转载请注明出处. 文章链接: http://blog.csdn.net/yhl_leo/article/details/49592361 编程时遇到BUG:err ...