Skip to content

Commit a51051b

Browse files
committed
task: complete cat javascript implementation
1 parent 45b8f91 commit a51051b

4 files changed

Lines changed: 71 additions & 98 deletions

File tree

implement-shell-tools/cat/cat-commander.mjs

Lines changed: 0 additions & 66 deletions
This file was deleted.

implement-shell-tools/cat/cat.mjs

Lines changed: 46 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,53 @@
11
import process from "node:process";
22
import { promises as fs } from "node:fs";
3+
import { Command } from "commander";
34

4-
const optionDefinitions = [
5-
{
6-
short: "-n",
7-
description: "Numbers all output lines",
8-
},
9-
{
10-
short: "-b",
11-
description: "Numbers non-blank output lines",
12-
},
13-
];
14-
15-
const argv = process.argv.slice(2);
16-
// if (argv.length != 1) {
17-
// console.error(
18-
// `Expected exactly 1 argument (a path) to be passed but got ${argv.length}.`,
19-
// );
20-
// process.exit(1);
21-
// }
22-
23-
console.log(argv);
24-
25-
const matchedOptions = optionDefinitions.find((option) => arg === option.short);
26-
const paths = [];
27-
for (const arg of argv) {
28-
if (arg.match(flagRegex)) {
29-
flags.push(arg);
30-
} else {
31-
paths.push(arg);
32-
}
33-
}
34-
console.log(flags, paths);
5+
const program = new Command();
6+
program
7+
.name("cat")
8+
.description("Concatenate files and print them to stdout")
9+
.option("-n, --number", "number all output lines")
10+
.option("-b, --number-nonblank", "number non-blank lines")
11+
.argument("<paths...>", "Paths to process");
12+
13+
program.parse();
14+
15+
const options = program.opts();
16+
const paths = program.args;
17+
let lineNumber = 1;
3518

3619
for (const path of paths) {
3720
const contents = await fs.readFile(path, "utf8");
38-
process.stdout.write(contents);
21+
const endsWithNewline = contents.endsWith("\n");
22+
23+
let lines = contents.split("\n");
24+
25+
if (endsWithNewline) {
26+
lines.pop();
27+
}
28+
29+
if (options.numberNonblank) {
30+
lines = numberLines(lines, false);
31+
} else if (options.number) {
32+
lines = numberLines(lines, true);
33+
}
34+
35+
let output = lines.join("\n");
36+
37+
if (endsWithNewline) {
38+
output += "\n";
39+
}
40+
41+
process.stdout.write(output);
42+
}
43+
44+
function numberLines(lines, includeBlankLines) {
45+
for (let i = 0; i < lines.length; i++) {
46+
if (includeBlankLines || lines[i].length > 0) {
47+
lines[i] = `${String(lineNumber).padStart(6, " ")}\t${lines[i]}`;
48+
lineNumber++;
49+
}
50+
}
51+
52+
return lines;
3953
}

implement-shell-tools/package-lock.json

Lines changed: 20 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

implement-shell-tools/package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"dependencies": {
3+
"commander": "^15.0.0"
4+
}
5+
}

0 commit comments

Comments
 (0)