Skip to content

Commit 775b0b7

Browse files
Implement 'cat' command alternative with line numbering options
1 parent e2ebd7f commit 775b0b7

1 file changed

Lines changed: 64 additions & 0 deletions

File tree

  • implement-shell-tools/cat

implement-shell-tools/cat/cat.js

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import { program } from "commander";
2+
import { promises as fs } from "node:fs";
3+
import process from "node:process";
4+
5+
// configure the CLI program with its name, description, arguments, options, and actions (the help instructions)
6+
program
7+
.name("cat")
8+
.description("An alternative to the 'cat' command")
9+
.argument("<files...>", "The file(s) to process")
10+
.option("-n, --number", "Number all output lines")
11+
.option("-b, --number-nonblank", "Number non-blank output lines")
12+
// actions to process the provided files with the specified options (-n, -b)
13+
.action(async (files, options) => {
14+
try {
15+
// call newCat for all files
16+
await newCat(files, options.number, options.numberNonblank)
17+
} catch (err) {
18+
console.error(`Error: ${err.message}`);
19+
}
20+
});
21+
22+
// parse command-line file arguments using the process.argv array
23+
program.parse(process.argv);
24+
25+
26+
async function newCat(files, numberLines, numberNonBlank) {
27+
let lineNumber = 1;
28+
29+
for (const file of files) {
30+
// read each file into a single text string
31+
try {
32+
const data = await fs.readFile(file, "utf8");
33+
// split that string into an array at \n where each element is a line from the file
34+
// e.g. lines = ["Line 1", "Line 2", "Line 3"]
35+
const lines = data.split("\n")
36+
37+
// remove trailing blank line caused by a trailing newline
38+
if (lines[lines.length - 1] === "") {
39+
lines.pop();
40+
}
41+
42+
for (const line of lines) {
43+
if (numberNonBlank) {
44+
// check what is left on the line after trimming (truthy = text, falsy = blank)
45+
if (line.trim()) {
46+
console.log(`${lineNumber.toString().padStart(6, ' ')} ${line}`);
47+
lineNumber++
48+
} else {
49+
console.log(line)
50+
}
51+
} else if (numberLines) {
52+
// number all lines
53+
console.log(`${lineNumber.toString().padStart(6, ' ')} ${line}`);
54+
lineNumber++
55+
} else {
56+
// if neither flag print normally
57+
console.log(line)
58+
}
59+
}
60+
} catch (err) {
61+
console.error(`Error reading file ${file}: ${err.message}`);
62+
}
63+
}
64+
}

0 commit comments

Comments
 (0)