Skip to content

Commit ccf9aa6

Browse files
committed
implement wc with -l -w -c flags
1 parent 19cae55 commit ccf9aa6

1 file changed

Lines changed: 82 additions & 0 deletions

File tree

  • implement-shell-tools/wc

implement-shell-tools/wc/wc.js

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import { promises as fs } from "node:fs";
2+
import process from "node:process";
3+
4+
const args = process.argv.slice(2);
5+
6+
const showLines = args.includes("-l");
7+
const showWords = args.includes("-w");
8+
const showBytes = args.includes("-c");
9+
10+
const noSpecificFlag = !showLines && !showWords && !showBytes;
11+
12+
const filePaths = args.filter((arg) => !arg.startsWith("-"));
13+
14+
if (filePaths.length === 0) {
15+
console.error("Usage: node wc.js [-l] [-w] [-c] <file...>");
16+
process.exit(1);
17+
}
18+
19+
const results = [];
20+
21+
for (const filePath of filePaths) {
22+
const content = await fs.readFile(filePath, "utf-8");
23+
24+
const lines = content.endsWith("\n")
25+
? content.split("\n").length - 1
26+
: content.split("\n").length;
27+
28+
const words = content.split(/\s+/).filter((w) => w.length > 0).length;
29+
30+
const bytes = Buffer.byteLength(content, "utf-8");
31+
32+
results.push({ filePath, lines, words, bytes });
33+
}
34+
35+
const totalLines = results.reduce((sum, r) => sum + r.lines, 0);
36+
const totalWords = results.reduce((sum, r) => sum + r.words, 0);
37+
const totalBytes = results.reduce((sum, r) => sum + r.bytes, 0);
38+
39+
let maxNumber;
40+
41+
if (noSpecificFlag) {
42+
maxNumber = Math.max(totalLines, totalWords, totalBytes);
43+
} else if (showLines) {
44+
maxNumber = totalLines;
45+
} else if (showWords) {
46+
maxNumber = totalWords;
47+
} else {
48+
maxNumber = totalBytes;
49+
}
50+
51+
const width = String(maxNumber).length + 2;
52+
53+
function formatLine(counts, label) {
54+
const parts = counts.map((n) => String(n).padStart(width, " "));
55+
return parts.join("") + " " + label;
56+
}
57+
58+
for (const { filePath, lines, words, bytes } of results) {
59+
if (noSpecificFlag) {
60+
process.stdout.write(formatLine([lines, words, bytes], filePath) + "\n");
61+
} else if (showLines) {
62+
process.stdout.write(formatLine([lines], filePath) + "\n");
63+
} else if (showWords) {
64+
process.stdout.write(formatLine([words], filePath) + "\n");
65+
} else if (showBytes) {
66+
process.stdout.write(formatLine([bytes], filePath) + "\n");
67+
}
68+
}
69+
70+
if (results.length > 1) {
71+
if (noSpecificFlag) {
72+
process.stdout.write(
73+
formatLine([totalLines, totalWords, totalBytes], "total") + "\n",
74+
);
75+
} else if (showLines) {
76+
process.stdout.write(formatLine([totalLines], "total") + "\n");
77+
} else if (showWords) {
78+
process.stdout.write(formatLine([totalWords], "total") + "\n");
79+
} else if (showBytes) {
80+
process.stdout.write(formatLine([totalBytes], "total") + "\n");
81+
}
82+
}

0 commit comments

Comments
 (0)