Skip to content

Instantly share code, notes, and snippets.

@gabssnake
Last active June 2, 2024 10:15
Show Gist options
  • Save gabssnake/2e492e76524118a84ea4ec650ae80626 to your computer and use it in GitHub Desktop.
Save gabssnake/2e492e76524118a84ea4ec650ae80626 to your computer and use it in GitHub Desktop.
Read lines from filename passed as argument or from stdin in Node.js
import fs from "node:fs/promises";
import readline from "node:readline/promises";
const { error: debug } = console;
/**
* Use as async iterator: `for await (const line of lineStream())`
* Works for calling with filename argument or piping stdin
* $ node script.mjs filename.txt
* $ node script.mjs < cat filename.txt
* $ cat filename.txt | node script.mjs
*/
export async function* lineStream(
filepath = process.argv.slice(2).shift(),
stream = process.stdin,
) {
if (filepath) {
debug("reading:", filepath);
try {
let data = await fs.readFile(filepath, "utf8");
for (let line of data.split(/\r\n|\n/)) {
if (ignore(line)) continue;
yield line;
}
} catch {
debug("failed to read file", filepath);
return;
}
} else {
debug("reading: stdin");
const lines = readline.createInterface({ input: stream });
for await (let line of lines) {
if (ignore(line)) continue;
yield line;
}
}
}
function ignore(line) {
// Supports single-line comments
if (line.startsWith("#")) return true;
// Ignores white-space
if (line.trim() === "") return true;
return false;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment