Skip to content

Commit f37f5e0

Browse files
committed
wc-implement-shell-tools
1 parent 72159a9 commit f37f5e0

1 file changed

Lines changed: 79 additions & 0 deletions

File tree

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
#!/usr/bin/env node
2+
import { program } from "commander";
3+
import { promises as fs } from "node:fs";
4+
import process from "node:process";
5+
6+
// Setup CLI with commander
7+
program
8+
.name("wc-clone")
9+
.description("A simplified implementation of the wc command")
10+
.option("-l", "count lines")
11+
.option("-w", "count words")
12+
.option("-c", "count bytes")
13+
.argument("[files...]", "files to process");
14+
15+
program.parse();
16+
17+
const options = program.opts();
18+
const files = program.args;
19+
20+
if (files.length === 0) {
21+
console.error("Please provide at least one file.");
22+
process.exit(1);
23+
}
24+
25+
// Helper function to count lines, words, bytes
26+
function countContent(content) {
27+
const lines = content.split("\n").length;
28+
const words = content.trim().split(/\s+/).filter(Boolean).length;
29+
const bytes = Buffer.byteLength(content, "utf-8");
30+
return { lines, words, bytes };
31+
}
32+
33+
// Process each file
34+
(async () => {
35+
let total = { lines: 0, words: 0, bytes: 0 };
36+
let multipleFiles = files.length > 1;
37+
38+
for (const file of files) {
39+
let content;
40+
try {
41+
content = await fs.readFile(file, "utf-8");
42+
} catch (err) {
43+
console.error(`wc-clone: cannot open '${file}': No such file`);
44+
continue;
45+
}
46+
47+
const counts = countContent(content);
48+
49+
total.lines += counts.lines;
50+
total.words += counts.words;
51+
total.bytes += counts.bytes;
52+
53+
// Determine what to display
54+
let output = "";
55+
if (options.l) output += `${counts.lines.toString().padStart(8)} `;
56+
if (options.w) output += `${counts.words.toString().padStart(8)} `;
57+
if (options.c) output += `${counts.bytes.toString().padStart(8)} `;
58+
if (!options.l && !options.w && !options.c) {
59+
// default: all counts
60+
output = `${counts.lines.toString().padStart(8)} ${counts.words.toString().padStart(8)} ${counts.bytes.toString().padStart(8)} `;
61+
}
62+
63+
output += file;
64+
console.log(output);
65+
}
66+
67+
// If multiple files, show total
68+
if (multipleFiles) {
69+
let output = "";
70+
if (options.l) output += `${total.lines.toString().padStart(8)} `;
71+
if (options.w) output += `${total.words.toString().padStart(8)} `;
72+
if (options.c) output += `${total.bytes.toString().padStart(8)} `;
73+
if (!options.l && !options.w && !options.c) {
74+
output = `${total.lines.toString().padStart(8)} ${total.words.toString().padStart(8)} ${total.bytes.toString().padStart(8)} `;
75+
}
76+
output += "total";
77+
console.log(output);
78+
}
79+
})();

0 commit comments

Comments
 (0)