Skip to content

Commit 5a74b43

Browse files
committed
feat: implement custom wc
1 parent 30170c8 commit 5a74b43

File tree

4 files changed

+74
-4
lines changed

4 files changed

+74
-4
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
node_modules
2+
demo*

implement-shell-tools/cat/customCat.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { promises as fs } from "node:fs";
44
import process from "node:process";
55

66
program
7-
.name("customCat")
7+
.name("ccat")
88
.description("CLI command to concatenate and print files")
99
.option("-n, --number", "Number all output lines starting, at 1")
1010
.option("-b, --nonBlank", "Number only non-blank lines, starting at 1")
@@ -36,6 +36,6 @@ for (const filePath of argv) {
3636
}
3737
});
3838
} catch (error) {
39-
console.error(`customCat: ${filePath}: No such file or directory.`);
39+
console.error(`ccat: ${filePath}: No such file or directory.`);
4040
}
4141
}

implement-shell-tools/ls/customLs.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { program } from "commander";
55
import { promises as fs } from "node:fs";
66

77
program
8-
.name("customLs")
8+
.name("cls")
99
.description("List contents of a directory")
1010
.option("-1", "Force output to be one entry per line")
1111
.option("-a", "Include hidden files")
@@ -38,7 +38,7 @@ async function listDir(dirPath, showHeader) {
3838
process.stdout.write(`${contents.join(" ")}\n`);
3939
}
4040
} catch (error) {
41-
console.error(`customLs: ${dirPath}: ${error.message}`);
41+
console.error(`cls: ${dirPath}: ${error.message}`);
4242
process.exit(1);
4343
}
4444
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#!/usr/bin/env node
2+
3+
import { program } from "commander";
4+
import process from "node:process";
5+
import { promises as fs } from "node:fs";
6+
7+
program
8+
.name("cwc")
9+
.description("Displays number of lines, words, and bytes in a file")
10+
.option("-l, --lines", "Counts number of newline characters")
11+
.option(
12+
"-w, --words",
13+
"Counts sequence of characters separated by whitespace",
14+
)
15+
.option("-c, --bytes", "Counts raw size of the files in bytes")
16+
.argument("<files...>", "File(s) to read and count");
17+
18+
program.parse();
19+
20+
const options = program.opts();
21+
const files = program.args;
22+
23+
const noFlags = !options.lines && !options.words && !options.bytes;
24+
25+
let totalLines = 0;
26+
let totalWords = 0;
27+
let totalBytes = 0;
28+
29+
async function countFiles(file) {
30+
try {
31+
const buffer = await fs.readFile(file);
32+
const content = buffer.toString("utf-8");
33+
34+
const lineCount = content === "" ? 0 : content.split("\n").length - 1;
35+
const wordCount = content.trim() ? content.trim().split(/\s+/).length : 0;
36+
const byteCount = buffer.length;
37+
38+
totalLines += lineCount;
39+
totalWords += wordCount;
40+
totalBytes += byteCount;
41+
42+
let result = "";
43+
44+
if (options.lines || noFlags) result += `${String(lineCount).padStart(8)}`;
45+
if (options.words || noFlags) result += `${String(wordCount).padStart(8)}`;
46+
if (options.bytes || noFlags) result += `${String(byteCount).padStart(8)}`;
47+
48+
process.stdout.write(`${result} ${file}\n`);
49+
} catch (error) {
50+
console.error(`cwc: ${file}: ${error.message}`);
51+
process.exit(1);
52+
}
53+
}
54+
55+
(async () => {
56+
for (const file of files) {
57+
await countFiles(file);
58+
}
59+
60+
if (files.length > 1) {
61+
let total = "";
62+
63+
if (options.lines || noFlags) total += `${String(totalLines).padStart(8)}`;
64+
if (options.words || noFlags) total += `${String(totalWords).padStart(8)}`;
65+
if (options.bytes || noFlags) total += `${String(totalBytes).padStart(8)}`;
66+
67+
process.stdout.write(`${total} total\n`);
68+
}
69+
})();

0 commit comments

Comments
 (0)