Skip to content

Commit 17c32ec

Browse files
authored
Create wc.js
1 parent cf41592 commit 17c32ec

File tree

1 file changed

+95
-0
lines changed
  • implement-shell-tools/wc

1 file changed

+95
-0
lines changed

implement-shell-tools/wc/wc.js

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import { program } from "commander";
2+
import { promises as fs } from "node:fs";
3+
4+
program
5+
.name("count-containing-words")
6+
.description("Counts words in a file that contain a particular character")
7+
.option(
8+
"-l",
9+
"The number of lines in each input file is written to the standard output."
10+
)
11+
.option(
12+
"-w",
13+
"The number of words in each input file is written to the standard output."
14+
)
15+
.option(
16+
"-c",
17+
"The number of bytes in each input file is written to the standard output."
18+
)
19+
.argument("<path...>", "The file path to process")
20+
.parse();
21+
22+
const argv = program.args;
23+
24+
const opts = program.opts();
25+
26+
const total = [];
27+
const output = [];
28+
const countsPerFile = [];
29+
let columnWidth = 0;
30+
31+
const flag_c = (content) => {
32+
return Buffer.byteLength(content, "utf8");
33+
};
34+
35+
const flag_w = (content) => {
36+
return content.match(/\b[\w']+\b/g).length;
37+
};
38+
39+
const flag_l = (content) => {
40+
return content.split("\n").length - 1;
41+
};
42+
43+
const countAndDisplay = async (path) => {
44+
const outputPerFile = [];
45+
const content = await fs.readFile(path, "utf-8");
46+
if (opts["l"]) {
47+
outputPerFile.push(flag_l(content));
48+
}
49+
if (opts["w"]) {
50+
outputPerFile.push(flag_w(content));
51+
}
52+
if (opts["c"]) {
53+
outputPerFile.push(flag_c(content));
54+
}
55+
if (argv.length > 1) {
56+
if (total.length == 0) {
57+
total.push(...outputPerFile);
58+
} else {
59+
for (let index = 0; index < outputPerFile.length; index++) {
60+
total[index] += outputPerFile[index];
61+
}
62+
}
63+
countsPerFile.push(...outputPerFile);
64+
}
65+
outputPerFile.push(path);
66+
output.push([...outputPerFile]);
67+
};
68+
69+
const handleInput = async () => {
70+
if (Object.keys(opts).length == 0) {
71+
["l", "w", "c"].forEach((key) => (opts[key] = true));
72+
}
73+
for (const path of argv) {
74+
await countAndDisplay(path);
75+
}
76+
const numOfColumns = Object.keys(opts).length;
77+
if (argv.length > 1) {
78+
total.push("total");
79+
output.push(total);
80+
}
81+
for (const row of output) {
82+
for (let i = 0; i < numOfColumns; i++) {
83+
columnWidth = Math.max(columnWidth, String(row[i]).length);
84+
}
85+
}
86+
87+
for (let row of output) {
88+
const line_parts = [];
89+
for (let i = 0; i < numOfColumns; i++) {
90+
line_parts.push(String(row[i]).padStart(columnWidth + 4));
91+
}
92+
console.log(line_parts.join(" "), row.at(-1));
93+
}
94+
};
95+
handleInput();

0 commit comments

Comments
 (0)