/ / Wie man von stdin Zeile für Zeile in Node - node.js, stdin liest

Wie liest man zeilenweise aus stdin in Node - node.js, stdin

Ich möchte eine Textdatei mit Node über einen Befehlszeilenaufruf wie folgt verarbeiten:

node app.js < input.txt

Jede Zeile der Datei muss einzeln verarbeitet werden, aber nach der Verarbeitung kann die Eingabezeile vergessen werden.

Mit dem On-Data-Listener des STDIN wird der Eingabedampf um eine Bytegröße zerlegt, sodass ich dies einstelle.

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);
});

Aber das scheint so schlampig. Um das erste und letzte Element des Zeilenarrays massieren zu müssen. Gibt es nicht einen eleganteren Weg, dies zu tun?

Antworten:

125 für die Antwort № 1

Du kannst den ... benutzen Zeile lesen Modul zum zeilenweisen Lesen von 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);
})

39 für die Antwort № 2

readline wurde speziell für die Arbeit mit Terminals entwickelt (d. h proccess.stdin.isTTY === true). Es gibt viele Module, die Split-Funktionen für generische Streams bereitstellen, z Teilt. Es macht die Dinge super einfach:

process.stdin.pipe(require("split")()).on("data", processLine)

function processLine (line) {
console.log(line + "!")
}

14 für die Antwort № 3
// Work on POSIX and Windows
var stdinBuffer = fs.readFileSync(0); // STDIN_FILENO = 0
console.log(stdinBuffer.toString());

0 für die Antwort № 4

In meinem Fall gab das Programm (elinks) Zeilen zurück, die leer aussahen, aber tatsächlich Sonderzeichen für das Terminal, Farbsteuerungscodes und Rücktaste enthielten grep Optionen, die in anderen Antworten vorgestellt wurden, haben bei mir nicht funktioniert. Also habe ich dieses kleine Skript in Node.js geschrieben. Ich habe die Datei angerufen tight, aber das ist nur ein zufälliger 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 für die Antwort № 5

Teilen für andere:

Stream Zeile für Zeile lesen, sollte gut für große Dateien sein, die in stdin geleitet werden, meine 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=/[rn]+/;
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 für die Antwort № 6
#!/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(/[rn|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);