Как обернуть readline от stdin для использования в конвейере? - PullRequest
0 голосов
/ 07 октября 2019

Я пишу скрипт для обработки вывода программы в консоли. Программа выдает огромное количество результатов, и я хочу отфильтровать их на лету, чтобы сохранить только то, что мне нужно.

Вот что у меня есть:

const {pipeline, Transform} = require('stream');
var readline = require('readline');

class FilterBlastOutput extends Transform {
    constructor(options) {
        super(options);
    }

    _transform(chunk,encoding,callback) {
        if(chunk === '\u0003')
            process.exit();
        let row = chunk.split("\t");
        if(row[3] >= 19 && row[4] <= 1) 
            callback(null,chunk);
    }
}

// Added after suggestion to use readline module
var rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
  terminal: false
});

pipeline(
        process.stdin,
        new FilterBlastOutput(),
        process.stdout,
        err => {
            if(err) {
                console.log("Pipeline failed: ");
            } else {
                console.log('Pipeline succeeded.')
            }
        }
);

В конвейере(..) Я использую process.stdin. Вместо process.stdin я хотел бы получить поток, предоставляющий данные в определенных блоках (строка). Как я могу это сделать?

Спасибо, Дженс

1 Ответ

1 голос
/ 07 октября 2019

Readline пример (без потока преобразования):

const readline = require('readline');

const rl = readline.createInterface({
  input: process.stdin
});

rl.on('line', filterBlastOutput)

function filterBlastOutput(line) {
  let row = line.split("\t");
  if(row[3] >= 19 && row[4] <= 1);
    process.stdout.write(line);
}

EDIT

Если вы хотите работать с pipeline, используйте split2 :

const {pipeline, Transform} = require('stream');
const split2 = require('split2');

class FilterBlastOutput extends Transform {
    constructor(options) {
        super(options);
    }

    _transform(chunk,encoding,callback) {
        if(chunk === '\u0003')
            process.exit();
        let row = chunk.split("\t");
        if(row[3] >= 19 && row[4] <= 1) 
            callback(null,chunk);
    }
}

pipeline(
        process.stdin,
        split2(),
        new FilterBlastOutput(),
        process.stdout,
        err => {
            if(err) {
                console.log("Pipeline failed: ");
            } else {
                console.log('Pipeline succeeded.')
            }
        }
);
...