← Runnable Projects

阅读中文版本

NDJSON Filter CLI

A Node CLI that reads newline-delimited JSON from stdin, keeps records matching a field selector, and writes NDJSON to stdout.

intermediatejavascriptunverified

Project

node-ndjson-filter

Entry point: ndjson-filter.mjs

Install

node --version

Run

cat events.ndjson | node ndjson-filter.mjs level=error

Test

node --test ndjson.test.mjs

Expected output

Writes only the records whose selected field equals the given value, one JSON object per line, preserving input order.

Dependencies

  • node >=20

What it does

Streams stdin line by line, parses each line as JSON, compares a dotted field path to the expected value, and writes matching records as NDJSON. A malformed line is reported to stderr and skipped so the stream continues.

import { createInterface } from 'node:readline';

const spec = process.argv[2];
if (!spec || !spec.includes('=')) { console.error('usage: ndjson-filter <field>=<value>'); process.exit(1); }
const [field, want] = spec.split('=', 2);
const value = want === 'true' ? true : want === 'false' ? false : want;

const get = (obj, path) => path.split('.').reduce((o, k) => (o == null ? o : o[k]), obj);

const rl = createInterface({ input: process.stdin, crlfDelay: Infinity });
for await (const line of rl) {
  if (!line.trim()) continue;
  try {
    const rec = JSON.parse(line);
    if (get(rec, field) === value) process.stdout.write(JSON.stringify(rec) + '\n');
  } catch {
    process.stderr.write('skipping malformed line\n');
  }
}

Run and verify

cat events.ndjson | node ndjson-filter.mjs level=error

Run the test command to check the implementation: node --test ndjson.test.mjs.

Expected Output

Given three events of which one has level “error”, the filtered stream contains only that line:

{"id":7,"level":"error","msg":"boom"}

Limitations

Equality only: no ranges or regular expressions. The field path supports dots but not array indexing, so values inside arrays must be flattened first.