How to read from stdin line by line in Node

I am looking to process a text file using node using a command line call like:

node app.js < input.txt

Each line of the file must be processed individually, but after processing the input line can be forgotten.

Using the on-data listener for stdin, I get the input pair placed byte size, so I set it.

 process.stdin.resume(); process.stdin.setEncoding('utf8'); var lingeringLine = ""; process.stdin.on('data', function(chunk) { lines = chunk.split("\n"); lines[0] = lingeringLine + lines[0]; lingeringLine = lines.pop(); lines.forEach(processLine); }); process.stdin.on('end', function() { processLine(lingeringLine); }); 

But it seems so messy. It is necessary to massage the first and last elements of the line array. Is there a more elegant way to do this?

+115
stdin
Nov 20 '13 at 3:39
source share
6 answers

You can use the readline module to read from stdin line by line:

 var readline = require('readline'); var rl = readline.createInterface({ input: process.stdin, output: process.stdout, terminal: false }); rl.on('line', function(line){ console.log(line); }) 
+144
Nov 20 '13 at 4:02
source share

readline specifically designed to work with the terminal (i.e. process.stdin.isTTY === true ). There are many modules that provide split functions for shared threads, such as split . This makes things super-easy:

 process.stdin.pipe(require('split')()).on('data', processLine) function processLine (line) { console.log(line + '!') } 
+46
Nov 20 '13 at 9:14
source share
 // Work on POSIX and Windows var stdinBuffer = fs.readFileSync(0); // STDIN_FILENO = 0 console.log(stdinBuffer.toString()); 
+26
Aug 03 '17 at 14:09 on
source share
 #!/usr/bin/env node const EventEmitter = require('events'); function stdinLineByLine() { const stdin = new EventEmitter(); let buff = ""; process.stdin .on('data', data => { buff += data; lines = buff.split(/[\r\n|\n]/); buff = lines.pop(); lines.forEach(line => stdin.emit('line', line)); }) .on('end', () => { if (buff.length > 0) stdin.emit('line', buff); }); return stdin; } const stdin = stdinLineByLine(); stdin.on('line', console.log); 
+4
Apr 21 '18 at 16:24
source share

In my case, the program (elinks) returned lines that looked empty, but in fact there were special terminal characters, color control codes and backspace, so the grep options provided in other answers did not work for me. So I wrote this little script in Node.js. I named the file tight , but it's just a random name.

 #!/usr/bin/env node function visible(a) { var R = '' for (var i = 0; i < a.length; i++) { if (a[i] == '\b') { R -= 1; continue; } if (a[i] == '\u001b') { while (a[i] != 'm' && i < a.length) i++ if (a[i] == undefined) break } else R += a[i] } return R } function empty(a) { a = visible(a) for (var i = 0; i < a.length; i++) { if (a[i] != ' ') return false } return true } var readline = require('readline') var rl = readline.createInterface({ input: process.stdin, output: process.stdout, terminal: false }) rl.on('line', function(line) { if (!empty(line)) console.log(line) }) 
0
Jun 13 '16 at 6:54 on
source share

For others:

reading the stream line by line should be good for large files sent to stdin, my version is:

 var n=0; function on_line(line,cb) { ////one each line console.log(n++,"line ",line); return cb(); ////end of one each line } var fs = require('fs'); var readStream = fs.createReadStream('all_titles.txt'); //var readStream = process.stdin; readStream.pause(); readStream.setEncoding('utf8'); var buffer=[]; readStream.on('data', (chunk) => { const newlines=/[\r\n]+/; var lines=chunk.split(newlines) if(lines.length==1) { buffer.push(lines[0]); return; } buffer.push(lines[0]); var str=buffer.join(''); buffer.length=0; readStream.pause(); on_line(str,()=>{ var i=1,l=lines.length-1; i--; function while_next() { i++; if(i<l) { return on_line(lines[i],while_next); } else { buffer.push(lines.pop()); lines.length=0; return readStream.resume(); } } while_next(); }); }).on('end', ()=>{ if(buffer.length) var str=buffer.join(''); buffer.length=0; on_line(str,()=>{ ////after end console.error('done') ////end after end }); }); readStream.resume(); 
0
Aug 14 '16 at 16:42 on
source share



All Articles