I\'m looking to process a text file with node using a command line call like:
node app.js < input.txt
Each line of the file needs to be proce
In my case the program (elinks) returned lines that looked empty, but in fact had special terminal characters, color control codes and backspace, so grep
options presented in other answers did not work for me. So I wrote this small script in Node.js. I called the file tight
, but that'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)
})
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);
})
#!/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);
readline
is specifically designed to work with terminal (that is process.stdin.isTTY === true
). There are a lot of modules which provide split functionality for generic streams, like split. It makes things super-easy:
process.stdin.pipe(require('split')()).on('data', processLine)
function processLine (line) {
console.log(line + '!')
}
if you want to ask the user number of lines first:
//array to save line by line
let xInputs = [];
const getInput = async (resolve)=>{
const readline = require('readline').createInterface({
input: process.stdin,
output: process.stdout,
});
readline.on('line',(line)=>{
readline.close();
xInputs.push(line);
resolve(line);
})
}
const getMultiInput = (numberOfInputLines,callback)=>{
let i = 0;
let p = Promise.resolve();
for (; i < numberOfInputLines; i++) {
p = p.then(_ => new Promise(resolve => getInput(resolve)));
}
p.then(()=>{
callback();
});
}
//get number of lines
const readline = require('readline').createInterface({
input: process.stdin,
output: process.stdout,
terminal: false
});
readline.on('line',(line)=>{
getMultiInput(line,()=>{
//get here the inputs from xinputs array
});
readline.close();
})
process.stdin.pipe(process.stdout);