Skip to content

Commit c326ecb

Browse files
committed
Implement wc command
1 parent 42cad0b commit c326ecb

1 file changed

Lines changed: 75 additions & 0 deletions

File tree

  • implement-shell-tools/wc

implement-shell-tools/wc/wc.mjs

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import { program } from "commander";
2+
import { promises as fs } from "node:fs";
3+
4+
program.name("wc");
5+
program.description("simple wc clone");
6+
program.option("-w, --words", "print word count");
7+
program.option("-l, --lines", "print line count");
8+
program.option("-c, --bytes", "print byte count");
9+
program.argument("[paths...]", "file(s) to process");
10+
program.parse();
11+
12+
const options = program.opts();
13+
const paths = program.args;
14+
15+
const noFlags = !options.words && !options.lines && !options.bytes;
16+
const showWords = options.words || noFlags;
17+
const showLines = options.lines || noFlags;
18+
const showBytes = options.bytes || noFlags;
19+
20+
function count(content) {
21+
const lines = content.split("\n").length - 1;
22+
const words = content.trim().split(/\s+/).filter(Boolean).length;
23+
const bytes = Buffer.byteLength(content);
24+
25+
return { lines, words, bytes };
26+
}
27+
28+
function formatCounts({ lines, words, bytes }, label = "") {
29+
const output = [];
30+
31+
if (showLines) {
32+
output.push(lines.toString().padStart(8));
33+
}
34+
35+
if (showWords) {
36+
output.push(words.toString().padStart(8));
37+
}
38+
39+
if (showBytes) {
40+
output.push(bytes.toString().padStart(8));
41+
}
42+
43+
if (label) {
44+
output.push(label);
45+
}
46+
47+
return output.join(" ");
48+
}
49+
50+
async function processFile(path) {
51+
try {
52+
const stat = await fs.stat(path);
53+
54+
if (stat.isDirectory()) {
55+
console.error(`${path}: Is a directory`);
56+
return;
57+
}
58+
59+
const content = await fs.readFile(path, { encoding: "utf-8" });
60+
const counts = count(content);
61+
const output = formatCounts(counts, path);
62+
63+
console.log(output);
64+
} catch (err) {
65+
console.error(`${path}: ${err.message}`);
66+
}
67+
}
68+
69+
try {
70+
for (const path of paths) {
71+
await processFile(path);
72+
}
73+
} catch (err) {
74+
console.error(err.message);
75+
}

0 commit comments

Comments
 (0)