다음과 같은 명령 줄 호출을 사용하여 노드가있는 텍스트 파일을 처리하려고합니다.
node app.js < input.txt
파일의 각 줄은 개별적으로 처리해야하지만 일단 처리되면 입력 줄을 잊을 수 있습니다.
stdin의 온 데이터 리스너를 사용하여 입력 스팀을 바이트 크기로 청크하여이를 설정했습니다.
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);
});
그러나 이것은 너무 조잡 해 보입니다. 라인 배열의 첫 번째 항목과 마지막 항목을 마사지해야합니다. 더 우아한 방법이 없습니까?
답변
readline 모듈을 사용하여 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);
})
답변
// Work on POSIX and Windows
var fs = require("fs");
var stdinBuffer = fs.readFileSync(0); // STDIN_FILENO = 0
console.log(stdinBuffer.toString());
답변
readline
터미널과 함께 작동하도록 특별히 설계되었습니다 process.stdin.isTTY === true
. 같은 일반적인 스트림에 대한 분할 기능을 제공하는 모듈이 많이 있습니다 분할 . 일이 매우 쉬워집니다.
process.stdin.pipe(require('split')()).on('data', processLine)
function processLine (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);
답변
다른 사람과 공유 :
스트림을 한 줄씩 읽으면 stdin, 내 버전으로 파이프 된 큰 파일에 적합해야합니다.
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();
답변
필자의 경우 프로그램 (elinks)은 비어있는 줄을 반환했지만 실제로 특수 터미널 문자, 색상 제어 코드 및 백 스페이스가 있었으므로 grep
다른 답변에 표시된 옵션은 작동하지 않았습니다. 그래서이 작은 스크립트를 Node.js에 작성했습니다. 나는 파일을 불렀지 tight
만 그것은 임의의 이름 일뿐입니다.
#!/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)
})