передача узла в строках для grep -f --fixed-strings - PullRequest
0 голосов
/ 14 июля 2020

Я хотел бы использовать grep --count --fixed-strings needles.txt < haystack.txt из среды Node.js.

Вместо файла для needles.txt у меня есть массив строк для поиска, а вместо haystack.txt У меня большая строка / буфер текста.

Какая комбинация методов child_process лучше всего использовать?

Что-то вроде:

import {spawn} from "child_process";

// haystack to search within
const haystack = "I am \n such a big string, do you\n see me?";
const readable = new Readable();
readable.push(haystack);
readable.push(null);

// the list of needles that would normally go in `--file=needles.txt`
const needles = ["find", "me", "or", "me"];

// spawn `fgrep`
// Q: How do I pass in `needles` as a string?
const fgrep = spawn(`fgrep`, [needles])

// pipe my haystack to fgrep
readable.pipe(fgrep.stdin);

grep документация

1 Ответ

1 голос
/ 14 июля 2020

Для grep аргументов -e позволяет указать несколько шаблонов:

grep -e 1 -e 2

JS для генерации аргументов будет примерно таким:

const needles = ["find", "me", "or", "me"];
const grep_pattern_args = needles.reduce((res, pattern) => {
    res.push('-e', pattern)
    return res
}, [])
const grep_args = [ '--count', '--fixed-strings', ...grep_pattern_args ]

3000 игл направляются в зону поражения execve s ограничение длины MAX_ARG_STRLEN в Linux 128kB . Если у вас длинные иглы, вам может потребоваться записать их в файл в любом случае, чтобы быть в безопасности.

spawn хорошо, так как вы получаете записываемый поток обратно для stdin, который вы можете писать так, как haystack читается / генерируется (при условии, что ваша настройка примера потока Readable надумана)

const stdout = []
const stderr = []
const fgrep = spawn('/usr/bin/fgrep', grep_args, { stdio: ['pipe', 'pipe', 'pipe'] })
fgrep.on('error', console.error)

// For larger output you can process more on the stream. 
fgrep.stdout.on('data', chunk => stdout.push(chunk))
fgrep.stderr.on('data', chunk => {
  process.stderr.write(chunk)
  stderr.push(chunk)
})

fgrep.on('close', (code) => {
  if (code !== 0) console.error(`grep process exited with code ${code}`)
  stdout.map(chunk => process.stdout.write(chunk))
})

fgrep.stdin.pipe(haystream)
...