NodeJS学习笔记 (25)逐行读取-readline(ok)
模块概览
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的有趣的工具,比如各种脚手架工具。限于篇幅不展开,感兴趣的同学可以研究下。
相关链接
NodeJS学习笔记 (25)逐行读取-readline(ok)的更多相关文章
- Nodejs学习笔记(十六)--- Pomelo介绍&入门
目录 前言&介绍 安装Pomelo 创建项目并启动 创建项目 项目结构说明 启动 测试连接 聊天服务器 新建gate和chat服务器 配置master.json 配置servers.json ...
- Nodejs学习笔记(十六)—Pomelo介绍&入门
前言&介绍 Pomelo:一个快速.可扩展.Node.js分布式游戏服务器框架 从三四年前接触Node.js开始就接触到了Pomelo,从Pomelo最初的版本到现在,总的来说网易出品还算不错 ...
- Nodejs学习笔记(四)——支持Mongodb
前言:回顾前面零零碎碎写的三篇挂着Nodejs学习笔记的文章,着实有点名不副实,当然,这篇可能还是要继续走着离主线越走越远的路子,从简短的介绍什么是Nodejs,到如何寻找一个可以调试的Nodejs ...
- Nodejs学习笔记(三)——一张图看懂Nodejs建站
前言:一条线,竖着放,如果做不到精进至深,那就旋转90°,至少也图个幅度宽广. 通俗解释上面的胡言乱语:还没学会爬,就学起走了?! 继上篇<Nodejs学习笔记(二)——Eclipse中运行调试 ...
- Nodejs学习笔记(二)——Eclipse中运行调试Nodejs
前篇<Nodejs学习笔记(一)——初识Nodejs>主要介绍了在搭建node环境过程中遇到的小问题以及搭建Eclipse开发Node环境的前提步骤.本篇主要介绍如何在Eclipse中运行 ...
- IOS学习笔记25—HTTP操作之ASIHTTPRequest
IOS学习笔记25—HTTP操作之ASIHTTPRequest 分类: iOS2012-08-12 10:04 7734人阅读 评论(3) 收藏 举报 iosios5网络wrapper框架新浪微博 A ...
- NodeJS学习笔记之Connect中间件模块(一)
NodeJS学习笔记之Connect中间件模块(一) http://www.jb51.net/article/60430.htm NodeJS学习笔记之Connect中间件模块(二) http://w ...
- Nodejs学习笔记(六)--- Node.js + Express 构建网站预备知识
目录 前言 新建express项目并自定义路由规则 如何提取页面中的公共部分? 如何提交表单并接收参数? GET 方式 POST 方式 如何字符串加密? 如何使用session? 如何使用cookie ...
- Nodejs学习笔记(十五)--- Node.js + Koa2 构建网站简单示例
目录 前言 搭建项目及其它准备工作 创建数据库 创建Koa2项目 安装项目其它需要包 清除冗余文件并重新规划项目目录 配置文件 规划示例路由,并新建相关文件 实现数据访问和业务逻辑相关方法 编写mys ...
随机推荐
- 文本编辑工具 Vim
Vim是Vi的升级版 vi和Vim的区别在于vi不会显示颜色,Vim会显示颜色 1.如果没有,可以安装 #yum install -y vim-enhanced
- [jzoj NOIP2018模拟11.02]
嗯T1忘记取模了,100到20 嗯T2忘记了那啥定理,暴力也写炸了,这题我认 嗯T3线段树合并分裂没有写炸,考场上就知道妥妥的70分.但是,分数出的时候听到有人说暴力也是70分,我???脸黑,枉我敲了 ...
- 14.boost最小生成树 kruskal_min_spainning_tree
#include <iostream> #include <boost/config.hpp> //图(矩阵实现) #include <boost/graph/adjac ...
- 路飞学城Python-Day13
[2.常用模块-模块的种类和导入方法] 1.什么是模块? 在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长.越来越不容易维护. 为了编写可维护的代码,我们把很多函数分组,分 ...
- 正则表达式中的/i
i = insensitive means case-insensitive 表示大小写不敏感
- iview中单击行,使得checkbox状态的方法
直接贴代码,这是一组jquery全选,全不选,反选代码 <!DOCTYPE html> <html lang="en"> <head> < ...
- Vue style里面使用@import引入外部css, 作用域是全局的解决方案
问题描述 使用@import引入外部css,作用域却是全局的 <template> </template> <script> export default { na ...
- 紫书 习题 8-22 UVa 1622 (构造法)
这道题的构造法真的复杂--要推一堆公式--这道题写了几天了--还是没写出来-- 一开始简单的觉得先左右来回, 然后上下来回, 然后把剩下的执行完了好了, 然后就WA. 然后换了个思路, 觉得是贪心, ...
- Qt5.7新特性
简述 Qt5.7发布了,新特性如下. 简述 新特性 C11 Support Required from the compiler New Features within existing module ...
- Android Bitmap太大导致ImageView不显示的问题
今天做我们的智能相冊的项目时,遇到了非常奇妙的问题,当照片太大时,导致ImageView.setImageBitmap不显示,上网上搜了非常多办法.感觉都不是那么靠谱.最后使用了简单粗暴的手段: // ...