Je cherche à traiter un fichier texte avec noeud en utilisant un appel de ligne de commande comme:
node app.js < input.txt
Chaque ligne du fichier doit être traitée individuellement, mais une fois traitée, la ligne en entrée peut être oubliée.
En utilisant le programme d’écoute sur les données du stdin, l’entrée Steam est fragmentée par une taille en octets et je la configure.
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);
});
Mais cela semble tellement bâclé. Avoir à masser autour du premier et du dernier élément du tableau de lignes. N'y a-t-il pas un moyen plus élégant de faire cela?
Vous pouvez utiliser le module readline pour lire ligne par ligne stdin:
var readline = require('readline');
var rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
terminal: false
});
rl.on('line', function(line){
console.log(line);
})
readline
est spécialement conçu pour fonctionner avec un terminal (c'est-à-dire process.stdin.isTTY === true
). De nombreux modules fournissent des fonctionnalités de partage pour les flux génériques, tels que split . Cela rend les choses super faciles:
process.stdin.pipe(require('split')()).on('data', processLine)
function processLine (line) {
console.log(line + '!')
}
// Work on POSIX and Windows
var stdinBuffer = fs.readFileSync(0); // STDIN_FILENO = 0
console.log(stdinBuffer.toString());
#!/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);
partage pour les autres:
lire le flux ligne par ligne, devrait être bon pour les gros fichiers redirigés dans stdin, ma version:
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();
Dans mon cas, le programme (elinks) renvoyait des lignes qui semblaient vides, mais qui comportaient en fait des caractères de terminal spéciaux, des codes de contrôle de couleur et des espaces arrière; les options grep
présentées dans d'autres réponses ne fonctionnaient donc pas pour moi. J'ai donc écrit ce petit script dans Node.js. J'ai appelé le fichier tight
, mais ce n'est qu'un nom aléatoire.
#!/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)
})