Skip to content

Commit 3a35a7a

Browse files
committed
wc implemented
1 parent 60b323e commit 3a35a7a

1 file changed

Lines changed: 141 additions & 0 deletions

File tree

  • implement-shell-tools/wc

implement-shell-tools/wc/wc.js

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
const fs = require("fs");
2+
const { allowedNodeEnvironmentFlags } = require("process");
3+
4+
const arguments = process.argv;
5+
const userArguments = arguments.slice(2);
6+
7+
const index = arguments[1].lastIndexOf("/");
8+
const currentWorkingDirectory = arguments[1].slice(0, index + 1);
9+
10+
const flags = userArguments
11+
.filter((argument) => argument.startsWith("-"))
12+
.map((argument) => argument.slice(1))
13+
.join("");
14+
15+
const flagHandlers = {
16+
l: lFlag,
17+
w: wFlag,
18+
c: cFlag,
19+
};
20+
21+
const metrics = ["lineCount", "wordCount", "byteSize"];
22+
const fileNames = userArguments.filter((argument) => !argument.startsWith("-"));
23+
const allFilesData = [];
24+
25+
extractFilesData();
26+
addTotals();
27+
const outputData = structuredClone(allFilesData);
28+
29+
let deleted = false;
30+
executeFlags();
31+
printOutput();
32+
33+
function extractFilesData() {
34+
fileNames.forEach((fileName) => {
35+
const fileData = {};
36+
fileData.name = fileName;
37+
fileData.text = readFile(fileName);
38+
fileData.lineCount = calculateLineCount(fileData.text);
39+
fileData.wordCount = calculateWordCount(fileData.text);
40+
fileData.byteSize = readByteSize(fileName);
41+
42+
allFilesData.push(fileData);
43+
});
44+
}
45+
46+
function addTotals() {
47+
if (allFilesData.length == 1) {
48+
return;
49+
}
50+
const totalsData = { name: "total" };
51+
metrics.forEach((metric) => {
52+
let sum = 0;
53+
allFilesData.forEach((file) => {
54+
sum += file[metric];
55+
});
56+
totalsData[metric] = sum;
57+
});
58+
allFilesData.push(totalsData);
59+
}
60+
61+
function readFile(fileName) {
62+
const filePath = currentWorkingDirectory + fileName;
63+
return fs.readFileSync(filePath, "utf8").trimEnd();
64+
}
65+
66+
function calculateLineCount(text) {
67+
return text.split("\n").length;
68+
}
69+
70+
function calculateWordCount(text) {
71+
return text.split(/\s+/).length;
72+
}
73+
74+
function readByteSize(fileName) {
75+
return fs.statSync(currentWorkingDirectory + fileName).size;
76+
}
77+
78+
function executeFlags() {
79+
for (const flag of flags) {
80+
if (flagHandlers[flag]) {
81+
allFilesContents = flagHandlers[flag]();
82+
} else {
83+
console.error(`wc: illegal option -- ${flag}\nusage: wc [-Lclmw] [file ...]`);
84+
process.exit(1);
85+
}
86+
}
87+
}
88+
89+
function lFlag() {
90+
deleteOutputs();
91+
allFilesData.forEach((sourceFile) => {
92+
const targetFile = outputData.find((file) => file.name === sourceFile.name);
93+
targetFile.lineCount = getIfTrue(sourceFile, "lineCount");
94+
});
95+
}
96+
97+
function wFlag() {
98+
deleteOutputs();
99+
allFilesData.forEach((sourceFile) => {
100+
const targetFile = outputData.find((file) => file.name === sourceFile.name);
101+
targetFile.wordCount = getIfTrue(sourceFile, "wordCount");
102+
});
103+
}
104+
105+
function cFlag() {
106+
deleteOutputs();
107+
allFilesData.forEach((sourceFile) => {
108+
const targetFile = outputData.find((file) => file.name === sourceFile.name);
109+
targetFile.byteSize = getIfTrue(sourceFile, "byteSize");
110+
});
111+
}
112+
113+
function deleteOutputs() {
114+
if (!deleted) {
115+
outputData.forEach((file) => {
116+
metrics.forEach((metric) => {
117+
delete file[metric];
118+
});
119+
});
120+
}
121+
deleted = true;
122+
}
123+
124+
function printOutput() {
125+
outputs = [];
126+
outputData.forEach((file) => {
127+
let outputString = "";
128+
metrics.forEach((metric) => {
129+
outputString += getIfTrue(file, metric);
130+
});
131+
outputString += ` ${file.name}`;
132+
console.log(outputString);
133+
});
134+
}
135+
136+
function getIfTrue(file, metric) {
137+
if (file[metric]) {
138+
return String(file[metric]).padStart(8, " ");
139+
}
140+
return "";
141+
}

0 commit comments

Comments
 (0)