Skip to content

Commit 2ac7f9a

Browse files
feat: build custom cat CLI using commander with file reading, line numbering and wildcard expansion
1 parent a9cb0f8 commit 2ac7f9a

File tree

1 file changed

+72
-0
lines changed
  • implement-shell-tools/cat/sample-files

1 file changed

+72
-0
lines changed
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
#!/usr/bin/env node
2+
const { program } = require("commander");
3+
const fs = require("fs");
4+
const path = require("path");
5+
6+
function expandWildcard(pattern) {
7+
const dir = path.dirname(pattern);
8+
const base = path.basename(pattern);
9+
10+
if (!base.includes("*")) return [pattern];
11+
12+
let files;
13+
try {
14+
files = fs.readdirSync(dir);
15+
} catch (e) {
16+
console.error(`cat: ${pattern}: No such directory`);
17+
return [];
18+
}
19+
20+
const regex = new RegExp("^" + base.replace(/\*/g, ".*") + "$");
21+
22+
return files
23+
.filter((f) => regex.test(f))
24+
.map((f) => path.join(dir, f));
25+
}
26+
27+
function printFile(filename, options) {
28+
let text;
29+
try {
30+
text = fs.readFileSync(filename, "utf-8");
31+
} catch {
32+
console.error(`cat: ${filename}: No such file`);
33+
return;
34+
}
35+
36+
const lines = text.split("\n");
37+
let counter = 1;
38+
39+
lines.forEach((line) => {
40+
if (options.numberAll) {
41+
console.log(`${counter} ${line}`);
42+
counter++;
43+
} else if (options.numberNonEmpty) {
44+
if (line.trim() === "") {
45+
console.log(line);
46+
} else {
47+
console.log(`${counter} ${line}`);
48+
counter++;
49+
}
50+
} else {
51+
console.log(line);
52+
}
53+
});
54+
}
55+
56+
program
57+
.name("mycat")
58+
.description("A custom implementation of the cat command")
59+
.argument("<files...>", "files or wildcard patterns")
60+
.option("-n, --number-all", "number all lines")
61+
.option("-b, --number-nonempty", "number non-empty lines")
62+
.action((patterns, options) => {
63+
let allFiles = [];
64+
65+
patterns.forEach((p) => {
66+
allFiles = allFiles.concat(expandWildcard(p));
67+
});
68+
69+
allFiles.forEach((file) => printFile(file, options));
70+
});
71+
72+
program.parse();

0 commit comments

Comments
 (0)