From 6b47b718bbed7f4708abefe8097c7774ae89b3a3 Mon Sep 17 00:00:00 2001 From: Droid-An Date: Fri, 25 Jul 2025 19:08:59 +0100 Subject: [PATCH 01/15] done basic ls functionality --- implement-shell-tools/ls/ls.js | 35 ++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 implement-shell-tools/ls/ls.js diff --git a/implement-shell-tools/ls/ls.js b/implement-shell-tools/ls/ls.js new file mode 100644 index 000000000..0b5dcdc13 --- /dev/null +++ b/implement-shell-tools/ls/ls.js @@ -0,0 +1,35 @@ +import { promises as fs } from "node:fs"; +import process from "node:process"; +// const path = require("node:path"); +import path from "node:path"; +const pathToFile = process.argv[1]; +// console.log(pathToFile); +const formattedPath = path.dirname(pathToFile); +// console.log(formattedPath); + +// ------ sync version (not working with promises) ------- + +// const files = fs.readdir(formattedPath, (files) => console.log(files)); + +// fs.readdir(formattedPath, (err, files) => { +// if (err) { +// console.error("Error reading directory:", err); +// return; +// } +// files.forEach(function (file) { +// // Do whatever you want to do with the file +// console.log(file); +// }); +// }); + +async function listFiles() { + try { + const files = await fs.readdir(formattedPath); + console.log(files.sort((a, b) => a.localeCompare(b)).join(" ")); + } catch (err) { + //is it goes to sterror + console.error("Error reading directory:", err); + } +} + +listFiles(); From fb5acb7b68f6a7dcc6d07f2c979c4281a21b5395 Mon Sep 17 00:00:00 2001 From: Droid-An Date: Sat, 26 Jul 2025 15:56:25 +0100 Subject: [PATCH 02/15] implemented -1 and -a flags --- implement-shell-tools/ls/ls.js | 71 +++++++++++++++++-------- implement-shell-tools/package-lock.json | 21 ++++++++ implement-shell-tools/package.json | 6 +++ 3 files changed, 76 insertions(+), 22 deletions(-) create mode 100644 implement-shell-tools/package-lock.json create mode 100644 implement-shell-tools/package.json diff --git a/implement-shell-tools/ls/ls.js b/implement-shell-tools/ls/ls.js index 0b5dcdc13..e9284959d 100644 --- a/implement-shell-tools/ls/ls.js +++ b/implement-shell-tools/ls/ls.js @@ -1,34 +1,61 @@ import { promises as fs } from "node:fs"; import process from "node:process"; -// const path = require("node:path"); import path from "node:path"; +import { program } from "commander"; + +program + .name("ls") + .description("Shows files in directory") + .option("-1", "list one file per line") + .option( + "-a", + "Used to list all files, including hidden files, in the current directory" + ) + .argument("[path]", "The file path to process"); + +program.parse(); + +const programArgv = program.args; + +if (programArgv.length > 0) { + console.log(programArgv); + console.log("k"); +} + +// i'm not using any arguments for now +// const argv = program.args; + +const char = program.opts(); + const pathToFile = process.argv[1]; + // console.log(pathToFile); const formattedPath = path.dirname(pathToFile); // console.log(formattedPath); -// ------ sync version (not working with promises) ------- - -// const files = fs.readdir(formattedPath, (files) => console.log(files)); - -// fs.readdir(formattedPath, (err, files) => { -// if (err) { -// console.error("Error reading directory:", err); -// return; -// } -// files.forEach(function (file) { -// // Do whatever you want to do with the file -// console.log(file); -// }); -// }); - async function listFiles() { - try { - const files = await fs.readdir(formattedPath); - console.log(files.sort((a, b) => a.localeCompare(b)).join(" ")); - } catch (err) { - //is it goes to sterror - console.error("Error reading directory:", err); + if (char["1"]) { + try { + const files = await fs.readdir(formattedPath); + const sortedOutput = files.sort((a, b) => a.localeCompare(b)); + files.forEach(function (file) { + console.log(file); + }); + } catch (err) { + //is it goes to stderror + console.error("Error reading directory:", err); + } + } else if (char["a"]) { + try { + const files = await fs.readdir(formattedPath); + const formattedOutput = files.sort((a, b) => a.localeCompare(b)); + formattedOutput.unshift(".."); + formattedOutput.unshift("."); + console.log(formattedOutput.join(" ")); + } catch (err) { + //is it goes to stderror + console.error("Error reading directory:", err); + } } } diff --git a/implement-shell-tools/package-lock.json b/implement-shell-tools/package-lock.json new file mode 100644 index 000000000..07c7f3f23 --- /dev/null +++ b/implement-shell-tools/package-lock.json @@ -0,0 +1,21 @@ +{ + "name": "implement-shell-tools", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "commander": "^14.0.0" + } + }, + "node_modules/commander": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.0.tgz", + "integrity": "sha512-2uM9rYjPvyq39NwLRqaiLtWHyDC1FvryJDa2ATTVims5YAS4PupsEQsDvP14FqhFr0P49CYDugi59xaxJlTXRA==", + "license": "MIT", + "engines": { + "node": ">=20" + } + } + } +} diff --git a/implement-shell-tools/package.json b/implement-shell-tools/package.json new file mode 100644 index 000000000..68279600c --- /dev/null +++ b/implement-shell-tools/package.json @@ -0,0 +1,6 @@ +{ + "type": "module", + "dependencies": { + "commander": "^14.0.0" + } +} From f094e2fda3e143753ea6aa7ba8cc3ec9cee426ce Mon Sep 17 00:00:00 2001 From: Droid-An Date: Sat, 26 Jul 2025 19:16:55 +0100 Subject: [PATCH 03/15] implemented 1 argument support --- implement-shell-tools/ls/ls.js | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/implement-shell-tools/ls/ls.js b/implement-shell-tools/ls/ls.js index e9284959d..9dff5d57f 100644 --- a/implement-shell-tools/ls/ls.js +++ b/implement-shell-tools/ls/ls.js @@ -11,29 +11,30 @@ program "-a", "Used to list all files, including hidden files, in the current directory" ) - .argument("[path]", "The file path to process"); + .argument("[sample-files]", "The file path to process"); program.parse(); -const programArgv = program.args; +/* probably can be assigned by ternary operator */ +let pathToFile = ""; -if (programArgv.length > 0) { - console.log(programArgv); - console.log("k"); +const programArgv = program.args; +if (programArgv.length == 1) { + pathToFile = programArgv[0]; +} else if (programArgv.length == 0) { + pathToFile = process.argv[1]; +} else { + console.error( + `Expected no more than 1 argument (sample-files) to be passed but got ${argv.length}.` + ); } -// i'm not using any arguments for now -// const argv = program.args; - const char = program.opts(); -const pathToFile = process.argv[1]; - -// console.log(pathToFile); const formattedPath = path.dirname(pathToFile); -// console.log(formattedPath); async function listFiles() { + /* can be rewritten using switch */ if (char["1"]) { try { const files = await fs.readdir(formattedPath); From 9907becf9196db405818ea17eb3aa7f3eb0fc1b4 Mon Sep 17 00:00:00 2001 From: Droid-An Date: Sun, 27 Jul 2025 08:45:30 +0100 Subject: [PATCH 04/15] done ls --- implement-shell-tools/ls/ls.js | 127 +++++++++++++++++++++++---------- 1 file changed, 91 insertions(+), 36 deletions(-) diff --git a/implement-shell-tools/ls/ls.js b/implement-shell-tools/ls/ls.js index 9dff5d57f..399a7ad06 100644 --- a/implement-shell-tools/ls/ls.js +++ b/implement-shell-tools/ls/ls.js @@ -1,4 +1,4 @@ -import { promises as fs } from "node:fs"; +import { Dirent, promises as fs } from "node:fs"; import process from "node:process"; import path from "node:path"; import { program } from "commander"; @@ -15,49 +15,104 @@ program program.parse(); -/* probably can be assigned by ternary operator */ let pathToFile = ""; const programArgv = program.args; -if (programArgv.length == 1) { - pathToFile = programArgv[0]; -} else if (programArgv.length == 0) { - pathToFile = process.argv[1]; -} else { - console.error( - `Expected no more than 1 argument (sample-files) to be passed but got ${argv.length}.` - ); -} - -const char = program.opts(); +// if (programArgv.length == 1) { +// console.log(programArgv[0]); +// fs.stat(programArgv[0], (err, stats) => { +// console.log(stats); +// if (!err) { +// if (stats.isFile()) { +// console.log("is file ? " + stats.isFile()); +// await listFiles(); +// } else if (stats.isDirectory()) { +// console.log("is directory? " + stats.isDirectory()); +// listFiles(); +// } +// } else throw err; +// }); -const formattedPath = path.dirname(pathToFile); +// pathToFile = programArgv[0]; +// } else if (programArgv.length == 0) { +// pathToFile = process.argv[1]; +// listFiles(); +// } else { +// console.error( +// `Expected no more than 1 argument (sample-files) to be passed but got ${argv.length}.` +// ); +// } -async function listFiles() { - /* can be rewritten using switch */ - if (char["1"]) { +(async () => { + if (programArgv.length === 1) { + pathToFile = programArgv[0]; try { - const files = await fs.readdir(formattedPath); - const sortedOutput = files.sort((a, b) => a.localeCompare(b)); - files.forEach(function (file) { - console.log(file); - }); + const stats = await fs.stat(pathToFile); + if (stats.isFile()) { + console.log("is file ? " + stats.isFile()); + await listFiles("file"); + } else if (stats.isDirectory()) { + console.log("is directory? " + stats.isDirectory()); + + listFiles("directory"); + } else { + console.error("Not a file or directory."); + } } catch (err) { - //is it goes to stderror - console.error("Error reading directory:", err); + console.error("Invalid path:", err.message); } - } else if (char["a"]) { - try { - const files = await fs.readdir(formattedPath); - const formattedOutput = files.sort((a, b) => a.localeCompare(b)); - formattedOutput.unshift(".."); - formattedOutput.unshift("."); - console.log(formattedOutput.join(" ")); - } catch (err) { - //is it goes to stderror - console.error("Error reading directory:", err); + } else if (programArgv.length === 0) { + pathToFile = process.cwd(); + await listFiles("directory"); + } else { + console.error( + `Expected no more than 1 argument (sample-files) but got ${programArgv.length}.` + ); + } +})(); + +const flag_1 = (files) => { + try { + files.forEach(function (file) { + console.log(file); + }); + } catch (err) { + //is it goes to stderror + console.error("Error reading directory:", err); + } +}; + +const flag_a = (files) => { + try { + files.unshift(".."); + files.unshift("."); + return files; + } catch (err) { + //is it goes to stderror + console.error("Error reading directory:", err); + } +}; + +async function listFiles(type) { + try { + let formattedPath = ""; + if (type == "directory") { + formattedPath = pathToFile; + } else if (type == "file") { + formattedPath = path.dirname(pathToFile); } + const char = program.opts(); + const files = await fs.readdir(formattedPath); + const sortedOutput = files.sort((a, b) => a.localeCompare(b)); + + if (char["1"] && char["a"]) { + flag_1(flag_a(sortedOutput)); + } else if (char["a"]) { + console.log(flag_a(sortedOutput).join(" ")); + } else if (char["1"]) { + flag_1(sortedOutput); + } + } catch (err) { + console.error("Error reading directory:", err); } } - -listFiles(); From 47ca36883ee4cc44ba718d0a8567d629f711c52e Mon Sep 17 00:00:00 2001 From: Droid-An Date: Sun, 27 Jul 2025 08:53:08 +0100 Subject: [PATCH 05/15] removed comments --- implement-shell-tools/ls/ls.js | 26 +------------------------- 1 file changed, 1 insertion(+), 25 deletions(-) diff --git a/implement-shell-tools/ls/ls.js b/implement-shell-tools/ls/ls.js index 399a7ad06..bacb651c8 100644 --- a/implement-shell-tools/ls/ls.js +++ b/implement-shell-tools/ls/ls.js @@ -1,4 +1,4 @@ -import { Dirent, promises as fs } from "node:fs"; +import { promises as fs } from "node:fs"; import process from "node:process"; import path from "node:path"; import { program } from "commander"; @@ -18,30 +18,6 @@ program.parse(); let pathToFile = ""; const programArgv = program.args; -// if (programArgv.length == 1) { -// console.log(programArgv[0]); -// fs.stat(programArgv[0], (err, stats) => { -// console.log(stats); -// if (!err) { -// if (stats.isFile()) { -// console.log("is file ? " + stats.isFile()); -// await listFiles(); -// } else if (stats.isDirectory()) { -// console.log("is directory? " + stats.isDirectory()); -// listFiles(); -// } -// } else throw err; -// }); - -// pathToFile = programArgv[0]; -// } else if (programArgv.length == 0) { -// pathToFile = process.argv[1]; -// listFiles(); -// } else { -// console.error( -// `Expected no more than 1 argument (sample-files) to be passed but got ${argv.length}.` -// ); -// } (async () => { if (programArgv.length === 1) { From 56ac17fd684e3e30c328ee91f52f69f55bb44582 Mon Sep 17 00:00:00 2001 From: Droid-An Date: Sun, 27 Jul 2025 16:33:34 +0100 Subject: [PATCH 06/15] wip: done support for one and multiple files --- implement-shell-tools/wc/wc.js | 65 ++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 implement-shell-tools/wc/wc.js diff --git a/implement-shell-tools/wc/wc.js b/implement-shell-tools/wc/wc.js new file mode 100644 index 000000000..203390d91 --- /dev/null +++ b/implement-shell-tools/wc/wc.js @@ -0,0 +1,65 @@ +import { program } from "commander"; +import { promises as fs } from "node:fs"; +import process from "node:process"; + +program + .name("count-containing-words") + .description("Counts words in a file that contain a particular character") + .option( + "-l", + "The number of lines in each input file is written to the standard output." + ) + .option( + "-w", + "The number of words in each input file is written to the standard output." + ) + .option( + "-c", + "The number of bytes in each input file is written to the standard output." + ) + .argument("", "The file path to process") + .parse(); + +const argv = program.args; +console.log(argv); + +const opts = program.opts(); +console.log("OPTS", opts); + +const total = [0, 0, 0]; + +const flag_l = (content) => { + return Buffer.byteLength(content, "utf8"); +}; + +const flag_w = (content) => { + return content.match(/\b[\w']+\b/g).length; +}; + +const flag_c = (content) => { + return content.split("\n").length - 1; +}; + +const countAndDisplay = async (path) => { + const content = await fs.readFile(path, "utf-8"); + if (opts["l"]) { + const countOfLines = flag_c(content); + total[0] += countOfLines; + return countOfLines; + } + const countOfWords = flag_w(content); + total[1] += countOfWords; + const countOfBytes = flag_l(content); + total[2] += countOfBytes; + console.log([countOfLines, countOfWords, countOfBytes, path].join(" ")); +}; + +const handleInput = async () => { + for (const path of argv) { + await countAndDisplay(path); + } + if (argv.length > 1) { + console.log(`${total.join(" ")} total`); + } +}; +handleInput(); From 59f994ceb1d88b30fcb021c377756d8360c1572c Mon Sep 17 00:00:00 2001 From: Droid-An Date: Sun, 27 Jul 2025 17:00:38 +0100 Subject: [PATCH 07/15] added new flag recognition system --- implement-shell-tools/wc/wc.js | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/implement-shell-tools/wc/wc.js b/implement-shell-tools/wc/wc.js index 203390d91..10846706d 100644 --- a/implement-shell-tools/wc/wc.js +++ b/implement-shell-tools/wc/wc.js @@ -27,31 +27,32 @@ const opts = program.opts(); console.log("OPTS", opts); const total = [0, 0, 0]; +const output = []; -const flag_l = (content) => { - return Buffer.byteLength(content, "utf8"); +const flag_c = (content) => { + output.push(Buffer.byteLength(content, "utf8")); }; const flag_w = (content) => { - return content.match(/\b[\w']+\b/g).length; + output.push(content.match(/\b[\w']+\b/g).length); }; -const flag_c = (content) => { - return content.split("\n").length - 1; +const flag_l = (content) => { + output.push(content.split("\n").length - 1); }; const countAndDisplay = async (path) => { const content = await fs.readFile(path, "utf-8"); if (opts["l"]) { - const countOfLines = flag_c(content); - total[0] += countOfLines; - return countOfLines; + flag_l(content); + } + if (opts["w"]) { + flag_w(content); + } + if (opts["c"]) { + flag_c(content); } - const countOfWords = flag_w(content); - total[1] += countOfWords; - const countOfBytes = flag_l(content); - total[2] += countOfBytes; - console.log([countOfLines, countOfWords, countOfBytes, path].join(" ")); + console.log([...output, path].join(" ")); }; const handleInput = async () => { From 49ce080689475c7a9cb886059f3a9ba034021714 Mon Sep 17 00:00:00 2001 From: Droid-An Date: Sun, 27 Jul 2025 18:05:19 +0100 Subject: [PATCH 08/15] done wc --- implement-shell-tools/wc/wc.js | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/implement-shell-tools/wc/wc.js b/implement-shell-tools/wc/wc.js index 10846706d..077634704 100644 --- a/implement-shell-tools/wc/wc.js +++ b/implement-shell-tools/wc/wc.js @@ -1,6 +1,5 @@ import { program } from "commander"; import { promises as fs } from "node:fs"; -import process from "node:process"; program .name("count-containing-words") @@ -26,7 +25,7 @@ console.log(argv); const opts = program.opts(); console.log("OPTS", opts); -const total = [0, 0, 0]; +const total = []; const output = []; const flag_c = (content) => { @@ -43,6 +42,7 @@ const flag_l = (content) => { const countAndDisplay = async (path) => { const content = await fs.readFile(path, "utf-8"); + output.splice(0); if (opts["l"]) { flag_l(content); } @@ -52,10 +52,24 @@ const countAndDisplay = async (path) => { if (opts["c"]) { flag_c(content); } + if (argv.length > 1) { + if (total.length == 0) { + total.push(...output); + } else { + for (let index = 0; index < output.length; index++) { + total[index] += output[index]; + } + } + } console.log([...output, path].join(" ")); }; const handleInput = async () => { + console.log("opts.length", opts.length); + if (Object.keys(opts).length == 0) { + ["l", "w", "c"].forEach((key) => (opts[key] = true)); + console.log(opts); + } for (const path of argv) { await countAndDisplay(path); } From b9e33e1c92ffb8adc72d1341ebe2afe51f5902e6 Mon Sep 17 00:00:00 2001 From: Droid-An Date: Sun, 27 Jul 2025 18:06:34 +0100 Subject: [PATCH 09/15] removed console.logs --- implement-shell-tools/wc/wc.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/implement-shell-tools/wc/wc.js b/implement-shell-tools/wc/wc.js index 077634704..f4d3570ee 100644 --- a/implement-shell-tools/wc/wc.js +++ b/implement-shell-tools/wc/wc.js @@ -20,10 +20,8 @@ program .parse(); const argv = program.args; -console.log(argv); const opts = program.opts(); -console.log("OPTS", opts); const total = []; const output = []; @@ -65,10 +63,8 @@ const countAndDisplay = async (path) => { }; const handleInput = async () => { - console.log("opts.length", opts.length); if (Object.keys(opts).length == 0) { ["l", "w", "c"].forEach((key) => (opts[key] = true)); - console.log(opts); } for (const path of argv) { await countAndDisplay(path); From c116a3418435c39da4b4bb1bb1dd3bb0ba494532 Mon Sep 17 00:00:00 2001 From: Droid-An Date: Mon, 28 Jul 2025 18:26:28 +0100 Subject: [PATCH 10/15] done -n flag and multiple files input support --- implement-shell-tools/cat/cat.js | 55 ++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 implement-shell-tools/cat/cat.js diff --git a/implement-shell-tools/cat/cat.js b/implement-shell-tools/cat/cat.js new file mode 100644 index 000000000..81a6c285c --- /dev/null +++ b/implement-shell-tools/cat/cat.js @@ -0,0 +1,55 @@ +import { promises as fs } from "node:fs"; +// import path from "node:path"; +import { program } from "commander"; +import { clearLine } from "node:readline"; + +program + .name("cat") + .description("Concatenate and print files") + .option("-n", "Number the output lines, starting at 1") + .option("-b", "Number the non-blank output lines, starting at 1") + .argument("", "The file path to process") + .parse(); + +const argv = program.args; + +const opts = program.opts(); + +const flag_n = (data) => { + const numberOfLines = data.split("\n").length - 1; + return numberOfLines; +}; +let number = 0; +async function example(path) { + try { + const data = await fs.readFile(path, { encoding: "utf8" }); + if (opts["n"]) { + const lines = data.split("\n"); + if (lines[lines.length - 1] === "") { + lines.pop(); + } + + for (let i = 0; i < lines.length; i++) { + const line = lines[i]; + const output = `${number + 1} ${line}`; + number += 1; + console.log(output.trimEnd()); + } + } else { + console.log(data.trimEnd()); + } + } catch (err) { + console.error(err); + } +} + +const handleInput = async () => { + for (const path of argv) { + await example(path); + } +}; + +handleInput(); +// for (const path of argv) { +// example(path); +// } From e9f95714543c52be15d85065962c0d1a9833b2c3 Mon Sep 17 00:00:00 2001 From: Droid-An Date: Mon, 28 Jul 2025 19:00:25 +0100 Subject: [PATCH 11/15] done cat --- implement-shell-tools/cat/cat.js | 47 ++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/implement-shell-tools/cat/cat.js b/implement-shell-tools/cat/cat.js index 81a6c285c..0c9970eaa 100644 --- a/implement-shell-tools/cat/cat.js +++ b/implement-shell-tools/cat/cat.js @@ -1,7 +1,5 @@ import { promises as fs } from "node:fs"; -// import path from "node:path"; import { program } from "commander"; -import { clearLine } from "node:readline"; program .name("cat") @@ -15,26 +13,36 @@ const argv = program.args; const opts = program.opts(); -const flag_n = (data) => { - const numberOfLines = data.split("\n").length - 1; - return numberOfLines; +const countLines = (data) => { + const lines = data.split("\n"); + if (lines[lines.length - 1] === "") { + lines.pop(); + } + + let lineNum = 1; + + for (const line of lines) { + if (opts.b) { + if (line.trim() === "") { + console.log(); + } else { + console.log(`${lineNum} ${line}`); + lineNum++; + } + } else if (opts.n) { + console.log(`${lineNum} ${line}`); + lineNum++; + } + } }; -let number = 0; + async function example(path) { try { const data = await fs.readFile(path, { encoding: "utf8" }); - if (opts["n"]) { - const lines = data.split("\n"); - if (lines[lines.length - 1] === "") { - lines.pop(); - } - - for (let i = 0; i < lines.length; i++) { - const line = lines[i]; - const output = `${number + 1} ${line}`; - number += 1; - console.log(output.trimEnd()); - } + if (opts["b"]) { + countLines(data); + } else if (opts["n"]) { + countLines(data); } else { console.log(data.trimEnd()); } @@ -50,6 +58,3 @@ const handleInput = async () => { }; handleInput(); -// for (const path of argv) { -// example(path); -// } From 7fcbf79b09b611fe37c6756843e42b6ca75304ec Mon Sep 17 00:00:00 2001 From: Droid-An Date: Sun, 3 Aug 2025 18:14:36 +0100 Subject: [PATCH 12/15] fixed ls --- implement-shell-tools/ls/ls.js | 39 ++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/implement-shell-tools/ls/ls.js b/implement-shell-tools/ls/ls.js index bacb651c8..a7e17a859 100644 --- a/implement-shell-tools/ls/ls.js +++ b/implement-shell-tools/ls/ls.js @@ -25,10 +25,8 @@ const programArgv = program.args; try { const stats = await fs.stat(pathToFile); if (stats.isFile()) { - console.log("is file ? " + stats.isFile()); await listFiles("file"); } else if (stats.isDirectory()) { - console.log("is directory? " + stats.isDirectory()); listFiles("directory"); } else { @@ -50,10 +48,10 @@ const programArgv = program.args; const flag_1 = (files) => { try { files.forEach(function (file) { - console.log(file); + console.log(file); + }); } catch (err) { - //is it goes to stderror console.error("Error reading directory:", err); } }; @@ -64,12 +62,12 @@ const flag_a = (files) => { files.unshift("."); return files; } catch (err) { - //is it goes to stderror console.error("Error reading directory:", err); } }; async function listFiles(type) { + let output = [] try { let formattedPath = ""; if (type == "directory") { @@ -81,12 +79,31 @@ async function listFiles(type) { const files = await fs.readdir(formattedPath); const sortedOutput = files.sort((a, b) => a.localeCompare(b)); - if (char["1"] && char["a"]) { - flag_1(flag_a(sortedOutput)); - } else if (char["a"]) { - console.log(flag_a(sortedOutput).join(" ")); - } else if (char["1"]) { - flag_1(sortedOutput); + // if (char["1"] && char["a"]) { + // flag_1(flag_a(sortedOutput)); + // } else if (char["a"]) { + // console.log(flag_a(sortedOutput).join(" ")); + // } else if (char["1"]) { + // flag_1(sortedOutput); + // } + + if (char["a"]){ + output = flag_a(sortedOutput) + } else { + sortedOutput.forEach(function (file) { + + if (file[0] != "."){ + output.push(file) + } + }) + + // output = sortedOutput + } + + if (char["1"]){ + flag_1(output) + } else { + console.log(output.join(" ")); } } catch (err) { console.error("Error reading directory:", err); From fabd47ab8ea1af4edfd48008e058ebe3b02e1dcd Mon Sep 17 00:00:00 2001 From: Droid-An Date: Sun, 3 Aug 2025 18:15:02 +0100 Subject: [PATCH 13/15] removed commented old code --- implement-shell-tools/ls/ls.js | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/implement-shell-tools/ls/ls.js b/implement-shell-tools/ls/ls.js index a7e17a859..272f99257 100644 --- a/implement-shell-tools/ls/ls.js +++ b/implement-shell-tools/ls/ls.js @@ -79,14 +79,6 @@ async function listFiles(type) { const files = await fs.readdir(formattedPath); const sortedOutput = files.sort((a, b) => a.localeCompare(b)); - // if (char["1"] && char["a"]) { - // flag_1(flag_a(sortedOutput)); - // } else if (char["a"]) { - // console.log(flag_a(sortedOutput).join(" ")); - // } else if (char["1"]) { - // flag_1(sortedOutput); - // } - if (char["a"]){ output = flag_a(sortedOutput) } else { @@ -96,8 +88,6 @@ async function listFiles(type) { output.push(file) } }) - - // output = sortedOutput } if (char["1"]){ From c61cbdf8c405aa267dcfbb04475ee1e3812f8b3b Mon Sep 17 00:00:00 2001 From: Droid-An Date: Sat, 13 Sep 2025 10:40:36 +0100 Subject: [PATCH 14/15] fixed ls --- implement-shell-tools/ls/ls.js | 73 ++++++++++++++-------------------- 1 file changed, 29 insertions(+), 44 deletions(-) diff --git a/implement-shell-tools/ls/ls.js b/implement-shell-tools/ls/ls.js index 272f99257..d2906380f 100644 --- a/implement-shell-tools/ls/ls.js +++ b/implement-shell-tools/ls/ls.js @@ -27,7 +27,6 @@ const programArgv = program.args; if (stats.isFile()) { await listFiles("file"); } else if (stats.isDirectory()) { - listFiles("directory"); } else { console.error("Not a file or directory."); @@ -46,56 +45,42 @@ const programArgv = program.args; })(); const flag_1 = (files) => { - try { - files.forEach(function (file) { - console.log(file); - - }); - } catch (err) { - console.error("Error reading directory:", err); - } + files.forEach(function (file) { + console.log(file); + }); }; const flag_a = (files) => { - try { - files.unshift(".."); - files.unshift("."); - return files; - } catch (err) { - console.error("Error reading directory:", err); - } + files.unshift(".."); + files.unshift("."); + return files; }; async function listFiles(type) { - let output = [] - try { - let formattedPath = ""; - if (type == "directory") { - formattedPath = pathToFile; - } else if (type == "file") { - formattedPath = path.dirname(pathToFile); - } - const char = program.opts(); - const files = await fs.readdir(formattedPath); - const sortedOutput = files.sort((a, b) => a.localeCompare(b)); - - if (char["a"]){ - output = flag_a(sortedOutput) - } else { - sortedOutput.forEach(function (file) { + let output = []; + let formattedPath = ""; + if (type == "directory") { + formattedPath = pathToFile; + } else if (type == "file") { + formattedPath = path.dirname(pathToFile); + } + const char = program.opts(); + const files = await fs.readdir(formattedPath); + const sortedOutput = files.sort((a, b) => a.localeCompare(b)); - if (file[0] != "."){ - output.push(file) - } - }) - } + if (char["a"]) { + output = flag_a(sortedOutput); + } else { + sortedOutput.forEach(function (file) { + if (file[0] != ".") { + output.push(file); + } + }); + } - if (char["1"]){ - flag_1(output) - } else { - console.log(output.join(" ")); - } - } catch (err) { - console.error("Error reading directory:", err); + if (char["1"]) { + flag_1(output); + } else { + console.log(output.join(" ")); } } From 85d6a7f2bfe940180dfcbf4b2f72f592e96abe94 Mon Sep 17 00:00:00 2001 From: Droid-An Date: Sun, 21 Sep 2025 19:04:12 +0100 Subject: [PATCH 15/15] fixed wc --- implement-shell-tools/wc/wc.js | 43 ++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/implement-shell-tools/wc/wc.js b/implement-shell-tools/wc/wc.js index f4d3570ee..1da1bd1bb 100644 --- a/implement-shell-tools/wc/wc.js +++ b/implement-shell-tools/wc/wc.js @@ -25,41 +25,45 @@ const opts = program.opts(); const total = []; const output = []; +const countsPerFile = []; +let columnWidth = 0; const flag_c = (content) => { - output.push(Buffer.byteLength(content, "utf8")); + return Buffer.byteLength(content, "utf8"); }; const flag_w = (content) => { - output.push(content.match(/\b[\w']+\b/g).length); + return content.match(/\b[\w']+\b/g).length; }; const flag_l = (content) => { - output.push(content.split("\n").length - 1); + return content.split("\n").length - 1; }; const countAndDisplay = async (path) => { + const outputPerFile = []; const content = await fs.readFile(path, "utf-8"); - output.splice(0); if (opts["l"]) { - flag_l(content); + outputPerFile.push(flag_l(content)); } if (opts["w"]) { - flag_w(content); + outputPerFile.push(flag_w(content)); } if (opts["c"]) { - flag_c(content); + outputPerFile.push(flag_c(content)); } if (argv.length > 1) { if (total.length == 0) { - total.push(...output); + total.push(...outputPerFile); } else { - for (let index = 0; index < output.length; index++) { - total[index] += output[index]; + for (let index = 0; index < outputPerFile.length; index++) { + total[index] += outputPerFile[index]; } } + countsPerFile.push(...outputPerFile); } - console.log([...output, path].join(" ")); + outputPerFile.push(path); + output.push([...outputPerFile]); }; const handleInput = async () => { @@ -69,8 +73,23 @@ const handleInput = async () => { for (const path of argv) { await countAndDisplay(path); } + const numOfColumns = Object.keys(opts).length; if (argv.length > 1) { - console.log(`${total.join(" ")} total`); + total.push("total"); + output.push(total); + } + for (const row of output) { + for (let i = 0; i < numOfColumns; i++) { + columnWidth = Math.max(columnWidth, String(row[i]).length); + } + } + + for (let row of output) { + const line_parts = []; + for (let i = 0; i < numOfColumns; i++) { + line_parts.push(String(row[i]).padStart(columnWidth + 4)); + } + console.log(line_parts.join(" "), row.at(-1)); } }; handleInput();