From 7260c898b6d43a558b07106daf4928069ce48755 Mon Sep 17 00:00:00 2001 From: Mansoor Munawar Date: Wed, 29 Jul 2026 02:50:44 +0100 Subject: [PATCH 1/4] Implemented cat,ls, and wc commant line tool. And also created an empty txt file to check my output for wc.mjs --- implement-shell-tools/cat/cat.mjs | 32 ++++++++++++++ implement-shell-tools/ls/ls.mjs | 22 ++++++++++ implement-shell-tools/wc/sample-files/4.txt | 0 implement-shell-tools/wc/wc.mjs | 48 +++++++++++++++++++++ 4 files changed, 102 insertions(+) create mode 100644 implement-shell-tools/cat/cat.mjs create mode 100644 implement-shell-tools/ls/ls.mjs create mode 100644 implement-shell-tools/wc/sample-files/4.txt create mode 100644 implement-shell-tools/wc/wc.mjs diff --git a/implement-shell-tools/cat/cat.mjs b/implement-shell-tools/cat/cat.mjs new file mode 100644 index 000000000..703e82763 --- /dev/null +++ b/implement-shell-tools/cat/cat.mjs @@ -0,0 +1,32 @@ +import process from "node:process"; +import { promises as fs } from "node:fs"; + +let args = process.argv.slice(2); +const flags = args.filter((arg) => arg.startsWith("-")); +const filePaths = args.filter((args) => !args.startsWith("-")); +let lineNumber = 1; + +for (const filePath of filePaths) { + const content = await fs.readFile(filePath, "utf-8"); + + if (flags.length == 0) { + process.stdout.write(content); + continue; + } + + const lines = content.split("\n"); + + for (const line of lines) { + if (flags.includes("-b")) { + if (line === "") { + console.log(); + } else { + console.log(`${lineNumber}\t${line}`); + lineNumber++; + } + } else if (flags.includes("-n")) { + console.log(`${lineNumber}\t${line}`); + lineNumber++; + } + } +} diff --git a/implement-shell-tools/ls/ls.mjs b/implement-shell-tools/ls/ls.mjs new file mode 100644 index 000000000..a0f2a5593 --- /dev/null +++ b/implement-shell-tools/ls/ls.mjs @@ -0,0 +1,22 @@ +import process from "node:process"; +import { promises as fs } from "node:fs"; + +const args = process.argv.slice(2); +const flags = args.filter((arg) => arg.startsWith("-")); +const path = args.filter((arg) => !arg.startsWith("-")); +let targetDir = path[0] || "."; +let files = await fs.readdir(targetDir); + +if (flags.includes("-a")) { + files.unshift(".", ".."); +} else { + files = files.filter((fileName) => !fileName.startsWith(".")); +} + +if (flags.includes("-1")) { + for (const file of files) { + console.log(file); + } +} else { + console.log(files.join(" ")); +} diff --git a/implement-shell-tools/wc/sample-files/4.txt b/implement-shell-tools/wc/sample-files/4.txt new file mode 100644 index 000000000..e69de29bb diff --git a/implement-shell-tools/wc/wc.mjs b/implement-shell-tools/wc/wc.mjs new file mode 100644 index 000000000..a63068dc9 --- /dev/null +++ b/implement-shell-tools/wc/wc.mjs @@ -0,0 +1,48 @@ +import process from "node:process"; +import { promises as fs } from "node:fs"; + +let filePaths = []; +let flag = null; +let numberOfWords; + +if (process.argv[2].startsWith("-")) { + flag = process.argv[2]; + filePaths = process.argv.slice(3); +} else { + filePaths = process.argv.slice(2); +} +for (const filePath of filePaths) { + const content = await fs.readFile(filePath, "utf-8"); + + if (flag === "-w") { + console.log(getWordCount(content)); + } else if (flag === "-l") { + console.log(getLineCount(content)); + } else if (flag === "-c") { + console.log(getByteCount(content), filePaths); + } else { + console.log( + getWordCount(content), + getLineCount(content), + getByteCount(content), + filePaths, + ); + } +} + +function getWordCount(text) { + const trimmed = text.trim(); + if (trimmed.length == 0) { + return 0; + } + return trimmed.split(/\s+/).length; +} + +function getLineCount(text) { + if (text.length == 0) return 0; + return text.split("\n").length - 1; +} + +function getByteCount(text) { + return Buffer.byteLength(text, "utf-8"); +} From b37eb2f14be00cc7a0d69eb4ad819b985baefebe Mon Sep 17 00:00:00 2001 From: Mansoor Munawar Date: Mon, 31 Aug 2026 23:09:15 +0100 Subject: [PATCH 2/4] implemented commander library to my cat, ls and wc file --- .DS_Store | Bin 0 -> 6148 bytes implement-shell-tools/.DS_Store | Bin 0 -> 6148 bytes implement-shell-tools/cat/cat.mjs | 53 ++++++++++----- implement-shell-tools/ls/ls.mjs | 45 ++++++++----- implement-shell-tools/package-lock.json | 25 +++++++ implement-shell-tools/package.json | 16 +++++ implement-shell-tools/wc/wc.mjs | 84 +++++++++++++++++------- 7 files changed, 166 insertions(+), 57 deletions(-) create mode 100644 .DS_Store create mode 100644 implement-shell-tools/.DS_Store create mode 100644 implement-shell-tools/package-lock.json create mode 100644 implement-shell-tools/package.json diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..9d00c88fe355a8ee309abe961ca9b18a1493cba2 GIT binary patch literal 6148 zcmeHKOHRW;41Iz9;kh239=opPc5%h9Eo$lywi-J;nDd{33;cBH8Qj}SI$g70;~446 zoRWcLAQ?yoPJjWu#3=I%$JEI{GLQ^>Goa@~VNZ}Ta_*Z literal 0 HcmV?d00001 diff --git a/implement-shell-tools/.DS_Store b/implement-shell-tools/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..a00719516cf91b3e1b4a5947b47214053c96a490 GIT binary patch literal 6148 zcmeH~Jr2S!425lAKw|00n1usyg9yP1xB#Mv35fwA)*PMZ9|j6Ds?f7!f3X{@?Hig} zM09gMtwlN!nZu2;vM?}3K9Ps?=hLk}UauD`q)n1mf_E~w{@O=U0V+TRr~nn90^?C2 zkMj9qJdeaDp#oH3BnsH~p}>tb*@FJ*K=2U&oT2Q7wa*e@u>x3=Er<$CqZN!+^)bZi z-VT=BSCcIm?V>q+Xx>?Eih*ggixwm>tquk%Km`U0Oe62?{NKU9&HsZIrc{6m{Fwqe z+wQj;yi}g8AFpTiLso6w;Gl0uc>4)JVn^{3?uP5d7GO=bASy8a2)GOkRN$uyJOQ!| B5HSD% literal 0 HcmV?d00001 diff --git a/implement-shell-tools/cat/cat.mjs b/implement-shell-tools/cat/cat.mjs index 703e82763..47651f179 100644 --- a/implement-shell-tools/cat/cat.mjs +++ b/implement-shell-tools/cat/cat.mjs @@ -1,32 +1,49 @@ import process from "node:process"; import { promises as fs } from "node:fs"; +import { program } from "commander"; + +program + .name("Cat") + .description("My version of cat command line tool") + .argument("", "Files to display") + .option("-n, --number", "Number all output lines") + .option("-b, --non-blank", "Number non empty output lines"); + +program.parse(); + +const { number, nonBlank } = program.opts(); +const filePaths = program.args; -let args = process.argv.slice(2); -const flags = args.filter((arg) => arg.startsWith("-")); -const filePaths = args.filter((args) => !args.startsWith("-")); let lineNumber = 1; for (const filePath of filePaths) { - const content = await fs.readFile(filePath, "utf-8"); + try { + const content = await fs.readFile(filePath, "utf-8"); - if (flags.length == 0) { - process.stdout.write(content); - continue; - } - - const lines = content.split("\n"); + if (!number && !nonBlank) { + process.stdout.write(content); + continue; + } + let text = content; + if (content.endsWith("\n")) { + text = content.slice(0, -1); + } + const lines = text.split("\n"); - for (const line of lines) { - if (flags.includes("-b")) { - if (line === "") { - console.log(); - } else { + for (const line of lines) { + if (nonBlank) { + if (line == "") { + console.log(); + } else { + console.log(`${lineNumber}\t${line}`); + lineNumber++; + } + } else if (number) { console.log(`${lineNumber}\t${line}`); lineNumber++; } - } else if (flags.includes("-n")) { - console.log(`${lineNumber}\t${line}`); - lineNumber++; } + } catch (error) { + console.error(`${error}`); } } diff --git a/implement-shell-tools/ls/ls.mjs b/implement-shell-tools/ls/ls.mjs index a0f2a5593..2c1574b4b 100644 --- a/implement-shell-tools/ls/ls.mjs +++ b/implement-shell-tools/ls/ls.mjs @@ -1,22 +1,37 @@ import process from "node:process"; import { promises as fs } from "node:fs"; +import { program } from "commander"; -const args = process.argv.slice(2); -const flags = args.filter((arg) => arg.startsWith("-")); -const path = args.filter((arg) => !arg.startsWith("-")); -let targetDir = path[0] || "."; -let files = await fs.readdir(targetDir); +program + .name("list") + .description("Implement my version of ls") + .argument("[paths...]", "The file path to process") + .option("-1, --one", "This list the item one per line") + .option("-a, --all", "This lists all of the files"); -if (flags.includes("-a")) { - files.unshift(".", ".."); -} else { - files = files.filter((fileName) => !fileName.startsWith(".")); -} +program.parse(); + +const { one, all } = program.opts(); +const paths = program.args; + +let targetDir = paths[0] || "."; + +try { + let files = await fs.readdir(targetDir); + + if (all) { + files = [".", "..", ...files].sort(); + } else { + files = files.filter((output) => !output.startsWith(".")).sort(); + } -if (flags.includes("-1")) { - for (const file of files) { - console.log(file); + if (one) { + for (const file of files) { + console.log(file); + } + } else { + console.log(files.join(" ")); } -} else { - console.log(files.join(" ")); +} catch (error) { + console.error(`${error}`); } diff --git a/implement-shell-tools/package-lock.json b/implement-shell-tools/package-lock.json new file mode 100644 index 000000000..5444e5c23 --- /dev/null +++ b/implement-shell-tools/package-lock.json @@ -0,0 +1,25 @@ +{ + "name": "implement-shell-tools", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "implement-shell-tools", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "commander": "^15.0.0" + } + }, + "node_modules/commander": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-15.0.0.tgz", + "integrity": "sha512-z67u4ZhzCL/Tydu1lJARtEZYWbWaN7oYLHbsuzocr6y4N6WZAagG3RQ4FW61V1/0+jImpj293XfrcYnd1qxtPg==", + "license": "MIT", + "engines": { + "node": ">=22.12.0" + } + } + } +} diff --git a/implement-shell-tools/package.json b/implement-shell-tools/package.json new file mode 100644 index 000000000..a05eb6f34 --- /dev/null +++ b/implement-shell-tools/package.json @@ -0,0 +1,16 @@ +{ + "name": "implement-shell-tools", + "version": "1.0.0", + "description": "Your task is to re-implement shell tools you have used.", + "main": "index.js", + "type": "module", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "commander": "^15.0.0" + } +} diff --git a/implement-shell-tools/wc/wc.mjs b/implement-shell-tools/wc/wc.mjs index a63068dc9..65c86e9c5 100644 --- a/implement-shell-tools/wc/wc.mjs +++ b/implement-shell-tools/wc/wc.mjs @@ -1,33 +1,69 @@ import process from "node:process"; import { promises as fs } from "node:fs"; +import { program } from "commander"; -let filePaths = []; -let flag = null; -let numberOfWords; +program + .name("Word Count") + .description("my implementation of wc") + .argument("", "The file path to process") + .option("-l", "Count for the total number of lines") + .option("-c", "Count the total number of bytes") + .option("-w", "Count the total number of words"); + +program.parse(); + +let filePaths = program.args; +let options = program.opts(); +let noFlags = !options.l && !options.w && !options.c; + +let totalLines = 0; +let totalWords = 0; +let totalBytes = 0; -if (process.argv[2].startsWith("-")) { - flag = process.argv[2]; - filePaths = process.argv.slice(3); -} else { - filePaths = process.argv.slice(2); -} for (const filePath of filePaths) { - const content = await fs.readFile(filePath, "utf-8"); - - if (flag === "-w") { - console.log(getWordCount(content)); - } else if (flag === "-l") { - console.log(getLineCount(content)); - } else if (flag === "-c") { - console.log(getByteCount(content), filePaths); - } else { - console.log( - getWordCount(content), - getLineCount(content), - getByteCount(content), - filePaths, - ); + try { + const content = await fs.readFile(filePath, "utf-8"); + const outputs = []; + + const lines = getLineCount(content); + const words = getWordCount(content); + const bytes = getByteCount(content); + + totalLines += lines; + totalWords += words; + totalBytes += bytes; + + if (noFlags || options.l) { + outputs.push(lines); + } + if (noFlags || options.w) { + outputs.push(words); + } + if (noFlags || options.c) { + outputs.push(bytes); + } + + outputs.push(filePath); + console.log(outputs.join("\t")); + } catch (err) { + console.error(`${err.message}`); + } +} + +if (filePaths.length > 1) { + const totalOutputs = []; + + if (noFlags || options.l) { + totalOutputs.push(totalLines); + } + if (noFlags || options.w) { + totalOutputs.push(totalWords); + } + if (noFlags || options.c) { + totalOutputs.push(totalBytes); } + totalOutputs.push("total"); + console.log(totalOutputs.join("\t")); } function getWordCount(text) { From 04105ac8ae33774bf1e71b99200a063ffca836dc Mon Sep 17 00:00:00 2001 From: Mansoor Munawar Date: Mon, 31 Aug 2026 23:48:49 +0100 Subject: [PATCH 3/4] implemented cowsay --- .DS_Store | Bin 6148 -> 6148 bytes implement-cowsay/.gitignore | 1 + implement-cowsay/main.py | 29 +++++++++++++++++++++++++++++ implement-cowsay/requirement.txt | 1 + 4 files changed, 31 insertions(+) create mode 100644 implement-cowsay/.gitignore create mode 100644 implement-cowsay/main.py create mode 100644 implement-cowsay/requirement.txt diff --git a/.DS_Store b/.DS_Store index 9d00c88fe355a8ee309abe961ca9b18a1493cba2..641dcebd633af52bb4914b317681cc0f1946cfc5 100644 GIT binary patch delta 52 zcmZoMXfc@J&&V<{U^goZ0|SG=WC2D|kz|H^hH{2thD3(Sw3OoHr2PCG#?3s8=h!y0 IbNuB8090|SHTWC2Fe%|VP?*(NsVZf58B%MSpdw+V{? diff --git a/implement-cowsay/.gitignore b/implement-cowsay/.gitignore new file mode 100644 index 000000000..1d17dae13 --- /dev/null +++ b/implement-cowsay/.gitignore @@ -0,0 +1 @@ +.venv diff --git a/implement-cowsay/main.py b/implement-cowsay/main.py new file mode 100644 index 000000000..7277eecac --- /dev/null +++ b/implement-cowsay/main.py @@ -0,0 +1,29 @@ +import argparse +import cowsay + +all_animals= sorted(cowsay.char_names) + +parser = argparse.ArgumentParser( + prog = "cowsay", + description= "Make animals say things" +) + +parser.add_argument( + "--animal", + choices = all_animals, + default = "cow", + help = "What do you want animal to say " + +) + +parser.add_argument( + "message", + nargs="+", + help = "The message to say" +) + +args = parser.parse_args() + +full_message = " ".join(args.message) + +print(cowsay.get_output_string(args.animal, full_message)) diff --git a/implement-cowsay/requirement.txt b/implement-cowsay/requirement.txt new file mode 100644 index 000000000..c6b9ffd0e --- /dev/null +++ b/implement-cowsay/requirement.txt @@ -0,0 +1 @@ +cowsay From d4b04375006bb68874bbce09f7a4dce61fe6c5f6 Mon Sep 17 00:00:00 2001 From: Mansoor Munawar Date: Tue, 1 Sep 2026 03:02:31 +0100 Subject: [PATCH 4/4] removed files added by mistake --- implement-shell-tools/cat/cat.mjs | 49 ------------ implement-shell-tools/ls/ls.mjs | 37 --------- implement-shell-tools/package-lock.json | 25 ------ implement-shell-tools/package.json | 16 ---- implement-shell-tools/wc/sample-files/4.txt | 0 implement-shell-tools/wc/wc.mjs | 84 --------------------- 6 files changed, 211 deletions(-) delete mode 100644 implement-shell-tools/cat/cat.mjs delete mode 100644 implement-shell-tools/ls/ls.mjs delete mode 100644 implement-shell-tools/package-lock.json delete mode 100644 implement-shell-tools/package.json delete mode 100644 implement-shell-tools/wc/sample-files/4.txt delete mode 100644 implement-shell-tools/wc/wc.mjs diff --git a/implement-shell-tools/cat/cat.mjs b/implement-shell-tools/cat/cat.mjs deleted file mode 100644 index 47651f179..000000000 --- a/implement-shell-tools/cat/cat.mjs +++ /dev/null @@ -1,49 +0,0 @@ -import process from "node:process"; -import { promises as fs } from "node:fs"; -import { program } from "commander"; - -program - .name("Cat") - .description("My version of cat command line tool") - .argument("", "Files to display") - .option("-n, --number", "Number all output lines") - .option("-b, --non-blank", "Number non empty output lines"); - -program.parse(); - -const { number, nonBlank } = program.opts(); -const filePaths = program.args; - -let lineNumber = 1; - -for (const filePath of filePaths) { - try { - const content = await fs.readFile(filePath, "utf-8"); - - if (!number && !nonBlank) { - process.stdout.write(content); - continue; - } - let text = content; - if (content.endsWith("\n")) { - text = content.slice(0, -1); - } - const lines = text.split("\n"); - - for (const line of lines) { - if (nonBlank) { - if (line == "") { - console.log(); - } else { - console.log(`${lineNumber}\t${line}`); - lineNumber++; - } - } else if (number) { - console.log(`${lineNumber}\t${line}`); - lineNumber++; - } - } - } catch (error) { - console.error(`${error}`); - } -} diff --git a/implement-shell-tools/ls/ls.mjs b/implement-shell-tools/ls/ls.mjs deleted file mode 100644 index 2c1574b4b..000000000 --- a/implement-shell-tools/ls/ls.mjs +++ /dev/null @@ -1,37 +0,0 @@ -import process from "node:process"; -import { promises as fs } from "node:fs"; -import { program } from "commander"; - -program - .name("list") - .description("Implement my version of ls") - .argument("[paths...]", "The file path to process") - .option("-1, --one", "This list the item one per line") - .option("-a, --all", "This lists all of the files"); - -program.parse(); - -const { one, all } = program.opts(); -const paths = program.args; - -let targetDir = paths[0] || "."; - -try { - let files = await fs.readdir(targetDir); - - if (all) { - files = [".", "..", ...files].sort(); - } else { - files = files.filter((output) => !output.startsWith(".")).sort(); - } - - if (one) { - for (const file of files) { - console.log(file); - } - } else { - console.log(files.join(" ")); - } -} catch (error) { - console.error(`${error}`); -} diff --git a/implement-shell-tools/package-lock.json b/implement-shell-tools/package-lock.json deleted file mode 100644 index 5444e5c23..000000000 --- a/implement-shell-tools/package-lock.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "name": "implement-shell-tools", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "implement-shell-tools", - "version": "1.0.0", - "license": "ISC", - "dependencies": { - "commander": "^15.0.0" - } - }, - "node_modules/commander": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-15.0.0.tgz", - "integrity": "sha512-z67u4ZhzCL/Tydu1lJARtEZYWbWaN7oYLHbsuzocr6y4N6WZAagG3RQ4FW61V1/0+jImpj293XfrcYnd1qxtPg==", - "license": "MIT", - "engines": { - "node": ">=22.12.0" - } - } - } -} diff --git a/implement-shell-tools/package.json b/implement-shell-tools/package.json deleted file mode 100644 index a05eb6f34..000000000 --- a/implement-shell-tools/package.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "implement-shell-tools", - "version": "1.0.0", - "description": "Your task is to re-implement shell tools you have used.", - "main": "index.js", - "type": "module", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "keywords": [], - "author": "", - "license": "ISC", - "dependencies": { - "commander": "^15.0.0" - } -} diff --git a/implement-shell-tools/wc/sample-files/4.txt b/implement-shell-tools/wc/sample-files/4.txt deleted file mode 100644 index e69de29bb..000000000 diff --git a/implement-shell-tools/wc/wc.mjs b/implement-shell-tools/wc/wc.mjs deleted file mode 100644 index 65c86e9c5..000000000 --- a/implement-shell-tools/wc/wc.mjs +++ /dev/null @@ -1,84 +0,0 @@ -import process from "node:process"; -import { promises as fs } from "node:fs"; -import { program } from "commander"; - -program - .name("Word Count") - .description("my implementation of wc") - .argument("", "The file path to process") - .option("-l", "Count for the total number of lines") - .option("-c", "Count the total number of bytes") - .option("-w", "Count the total number of words"); - -program.parse(); - -let filePaths = program.args; -let options = program.opts(); -let noFlags = !options.l && !options.w && !options.c; - -let totalLines = 0; -let totalWords = 0; -let totalBytes = 0; - -for (const filePath of filePaths) { - try { - const content = await fs.readFile(filePath, "utf-8"); - const outputs = []; - - const lines = getLineCount(content); - const words = getWordCount(content); - const bytes = getByteCount(content); - - totalLines += lines; - totalWords += words; - totalBytes += bytes; - - if (noFlags || options.l) { - outputs.push(lines); - } - if (noFlags || options.w) { - outputs.push(words); - } - if (noFlags || options.c) { - outputs.push(bytes); - } - - outputs.push(filePath); - console.log(outputs.join("\t")); - } catch (err) { - console.error(`${err.message}`); - } -} - -if (filePaths.length > 1) { - const totalOutputs = []; - - if (noFlags || options.l) { - totalOutputs.push(totalLines); - } - if (noFlags || options.w) { - totalOutputs.push(totalWords); - } - if (noFlags || options.c) { - totalOutputs.push(totalBytes); - } - totalOutputs.push("total"); - console.log(totalOutputs.join("\t")); -} - -function getWordCount(text) { - const trimmed = text.trim(); - if (trimmed.length == 0) { - return 0; - } - return trimmed.split(/\s+/).length; -} - -function getLineCount(text) { - if (text.length == 0) return 0; - return text.split("\n").length - 1; -} - -function getByteCount(text) { - return Buffer.byteLength(text, "utf-8"); -}