Skip to content

Commit 0cf4afc

Browse files
committed
Implement cat, ls, and wc commands with line, word, and byte counting features
1 parent 3f26722 commit 0cf4afc

3 files changed

Lines changed: 184 additions & 0 deletions

File tree

implement-shell-tools/cat/cat.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
const fs = require("fs");
2+
3+
const args = process.argv.slice(2);
4+
5+
let numberLines = false;
6+
let numberNonBlank = false;
7+
const files = [];
8+
9+
for (const arg of args) {
10+
if (arg === "-n") {
11+
numberLines = true;
12+
} else if (arg === "-b") {
13+
numberNonBlank = true;
14+
} else {
15+
files.push(arg);
16+
}
17+
}
18+
19+
if (numberNonBlank) {
20+
numberLines = false;
21+
}
22+
23+
let lineNumber = 1;
24+
25+
for (const file of files) {
26+
try {
27+
const contents = fs.readFileSync(file, "utf8");
28+
const lines = contents.split("\n");
29+
30+
lines.forEach((line, index) => {
31+
const output = index < lines.length - 1 ? line + "\n" : line;
32+
33+
if (numberNonBlank) {
34+
if (line.trim() === "") {
35+
process.stdout.write(output);
36+
} else {
37+
process.stdout.write(`${String(lineNumber).padStart(6)}\t${output}`);
38+
lineNumber++;
39+
}
40+
} else if (numberLines) {
41+
process.stdout.write(`${String(lineNumber).padStart(6)}\t${output}`);
42+
lineNumber++;
43+
} else {
44+
process.stdout.write(output);
45+
}
46+
});
47+
} catch (err) {
48+
console.error(`cat: ${file}: ${err.message}`);
49+
}
50+
}

implement-shell-tools/ls/ls.js

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
const fs = require("fs");
2+
3+
const args = process.argv.slice(2);
4+
5+
let onePerLine = false;
6+
let showHidden = false;
7+
let paths = [];
8+
9+
for (let i = 0; i < args.length; i++) {
10+
if (args[i] === "-1") {
11+
onePerLine = true;
12+
} else if (args[i] === "-a") {
13+
showHidden = true;
14+
} else {
15+
paths.push(args[i]);
16+
}
17+
}
18+
if (paths.length === 0) {
19+
paths.push(".");
20+
}
21+
22+
for (let i = 0; i < paths.length; i++) {
23+
let path = paths[i];
24+
25+
try {
26+
if (fs.statSync(path).isFile()) {
27+
console.log(path);
28+
} else {
29+
let files = fs.readdirSync(path);
30+
31+
files.sort();
32+
33+
for (let j = 0; j < files.length; j++) {
34+
let file = files[j];
35+
if (!showHidden && file.startsWith(".")) {
36+
continue;
37+
}
38+
if (onePerLine) {
39+
console.log(file);
40+
} else {
41+
process.stdout.write(file + " ");
42+
}
43+
}
44+
45+
if (!onePerLine) {
46+
console.log();
47+
}
48+
}
49+
} catch (error) {
50+
console.log("Cannot access: " + path);
51+
}
52+
}

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+
const fs = require("fs");
2+
3+
const args = process.argv.slice(2);
4+
5+
let countLines = false;
6+
let countWords = false;
7+
let countBytes = false;
8+
9+
let files = [];
10+
11+
for (let arg of args) {
12+
if (arg === "-l") {
13+
countLines = true;
14+
} else if (arg === "-w") {
15+
countWords = true;
16+
} else if (arg === "-c") {
17+
countBytes = true;
18+
} else {
19+
files.push(arg);
20+
}
21+
}
22+
23+
if (!countLines && !countWords && !countBytes) {
24+
countLines = true;
25+
countWords = true;
26+
countBytes = true;
27+
}
28+
29+
let totalLines = 0;
30+
let totalWords = 0;
31+
let totalBytes = 0;
32+
let filesCounted = 0;
33+
34+
function countFile(fileName) {
35+
try {
36+
const content = fs.readFileSync(fileName, "utf8");
37+
let lines = content.split("\n").length - 1;
38+
let words = content
39+
.trim()
40+
.split(/\s+/)
41+
.filter((word) => word.length > 0).length;
42+
let bytes = Buffer.byteLength(content);
43+
totalLines += lines;
44+
totalWords += words;
45+
totalBytes += bytes;
46+
filesCounted++;
47+
let result = "";
48+
if (countLines) {
49+
result += lines + " ";
50+
}
51+
if (countWords) {
52+
result += words + " ";
53+
}
54+
if (countBytes) {
55+
result += bytes + " ";
56+
}
57+
result += fileName;
58+
console.log(result);
59+
} catch (error) {
60+
console.log("Cannot read file: " + fileName);
61+
}
62+
}
63+
64+
for (let file of files) {
65+
countFile(file);
66+
}
67+
68+
if (filesCounted > 1) {
69+
let result = "";
70+
if (countLines) {
71+
result += totalLines + " ";
72+
}
73+
if (countWords) {
74+
result += totalWords + " ";
75+
}
76+
if (countBytes) {
77+
result += totalBytes + " ";
78+
}
79+
result += "total";
80+
81+
console.log(result);
82+
}

0 commit comments

Comments
 (0)