From d936ded0772ae8b351de99135691f2c4e6011110 Mon Sep 17 00:00:00 2001 From: SlimMicheals Date: Tue, 7 Apr 2026 22:19:23 +0200 Subject: [PATCH 01/10] Implement basic cat command --- implement-shell-tools/cat/cat.js | 8 ++++++++ 1 file changed, 8 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..84d452660 --- /dev/null +++ b/implement-shell-tools/cat/cat.js @@ -0,0 +1,8 @@ +const fs = require("fs"); + +const args = process.argv.slice(2); + +for (const file of args) { + const content = fs.readFileSync(file, "utf8"); + process.stdout.write(content); +} \ No newline at end of file From c1d33705f149b111b91eebaa99334448915984c9 Mon Sep 17 00:00:00 2001 From: SlimMicheals Date: Tue, 7 Apr 2026 22:33:55 +0200 Subject: [PATCH 02/10] Add -n flag to cat for line numbering --- implement-shell-tools/cat/cat.js | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/implement-shell-tools/cat/cat.js b/implement-shell-tools/cat/cat.js index 84d452660..144d3b2d9 100644 --- a/implement-shell-tools/cat/cat.js +++ b/implement-shell-tools/cat/cat.js @@ -2,7 +2,22 @@ const fs = require("fs"); const args = process.argv.slice(2); -for (const file of args) { +// check if -n is included +const showLineNumbers = args.includes("-n"); + +// filter out the flag, keep only file names +const files = args.filter(arg => arg !== "-n"); + +for (const file of files) { const content = fs.readFileSync(file, "utf8"); - process.stdout.write(content); + + if (showLineNumbers) { + const lines = content.split("\n"); + + lines.forEach((line, index) => { + console.log(`${index + 1} ${line}`); + }); + } else { + process.stdout.write(content); + } } \ No newline at end of file From 3aa62e07d62d35eaf3ba4e4402c279620f50be5d Mon Sep 17 00:00:00 2001 From: SlimMicheals Date: Tue, 7 Apr 2026 22:47:55 +0200 Subject: [PATCH 03/10] Add -b flag to cat for numbering non-empty lines --- implement-shell-tools/cat/cat.js | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/implement-shell-tools/cat/cat.js b/implement-shell-tools/cat/cat.js index 144d3b2d9..2da8c591d 100644 --- a/implement-shell-tools/cat/cat.js +++ b/implement-shell-tools/cat/cat.js @@ -2,16 +2,27 @@ const fs = require("fs"); const args = process.argv.slice(2); -// check if -n is included const showLineNumbers = args.includes("-n"); +const numberNonEmptyLines = args.includes("-b"); -// filter out the flag, keep only file names -const files = args.filter(arg => arg !== "-n"); +const files = args.filter(arg => arg !== "-n" && arg !== "-b"); for (const file of files) { const content = fs.readFileSync(file, "utf8"); - if (showLineNumbers) { + if (numberNonEmptyLines) { + const lines = content.split("\n"); + let lineNumber = 1; + + lines.forEach((line) => { + if (line.trim() !== "") { + console.log(`${lineNumber} ${line}`); + lineNumber++; + } else { + console.log(line); + } + }); + } else if (showLineNumbers) { const lines = content.split("\n"); lines.forEach((line, index) => { From 690621b8f2e17558d3d276aae7013d8f1d41c04e Mon Sep 17 00:00:00 2001 From: SlimMicheals Date: Tue, 7 Apr 2026 22:58:58 +0200 Subject: [PATCH 04/10] Implement basic ls -1 functionality --- implement-shell-tools/ls/ls.js | 8 ++++++++ 1 file changed, 8 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..f99508196 --- /dev/null +++ b/implement-shell-tools/ls/ls.js @@ -0,0 +1,8 @@ +const fs = require("fs"); + +// read current directory +const files = fs.readdirSync("."); + +files.forEach(file => { + console.log(file); +}); \ No newline at end of file From 72f8744fc4ba1684ddb16a771bb43ade15e74b14 Mon Sep 17 00:00:00 2001 From: SlimMicheals Date: Tue, 7 Apr 2026 23:08:36 +0200 Subject: [PATCH 05/10] Add directory argument support to ls --- implement-shell-tools/ls/ls.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/implement-shell-tools/ls/ls.js b/implement-shell-tools/ls/ls.js index f99508196..8573d9a46 100644 --- a/implement-shell-tools/ls/ls.js +++ b/implement-shell-tools/ls/ls.js @@ -1,7 +1,9 @@ const fs = require("fs"); -// read current directory -const files = fs.readdirSync("."); +const args = process.argv.slice(2); +const target = args[0] || "."; + +const files = fs.readdirSync(target); files.forEach(file => { console.log(file); From 51a2abd54b0b8b57b89a5c1f369b445dd6965eb2 Mon Sep 17 00:00:00 2001 From: SlimMicheals Date: Tue, 7 Apr 2026 23:12:51 +0200 Subject: [PATCH 06/10] Add -a flag to show hidden files in ls --- implement-shell-tools/ls/ls.js | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/implement-shell-tools/ls/ls.js b/implement-shell-tools/ls/ls.js index 8573d9a46..341ab34a2 100644 --- a/implement-shell-tools/ls/ls.js +++ b/implement-shell-tools/ls/ls.js @@ -1,9 +1,20 @@ const fs = require("fs"); const args = process.argv.slice(2); -const target = args[0] || "."; -const files = fs.readdirSync(target); +const showAll = args.includes("-a"); + +// remove -a from arguments +const filteredArgs = args.filter(arg => arg !== "-a"); + +const target = filteredArgs[0] || "."; + +let files = fs.readdirSync(target); + +// hide hidden files if -a is NOT used +if (!showAll) { + files = files.filter(file => !file.startsWith(".")); +} files.forEach(file => { console.log(file); From aeca96eb4a2b2d29c063a8f30fddce4ab9042258 Mon Sep 17 00:00:00 2001 From: SlimMicheals Date: Tue, 7 Apr 2026 23:31:29 +0200 Subject: [PATCH 07/10] implement wc for single file (lines, words, characters) --- implement-shell-tools/wc/wc.js | 18 ++++++++++++++++++ 1 file changed, 18 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..dea5ad059 --- /dev/null +++ b/implement-shell-tools/wc/wc.js @@ -0,0 +1,18 @@ +const fs = require("fs"); + +const args = process.argv.slice(2); + +const file = args[0]; + +const content = fs.readFileSync(file, "utf8"); + +// count lines +const lines = content.split("\n").length; + +// count words +const words = content.trim().split(/\s+/).length; + +// count characters +const chars = content.length; + +console.log(lines, words, chars, file); \ No newline at end of file From e8b9d2a42b160599e247aa85985aa3b461b828c2 Mon Sep 17 00:00:00 2001 From: SlimMicheals Date: Tue, 7 Apr 2026 23:42:27 +0200 Subject: [PATCH 08/10] Add multiple file support to wc --- implement-shell-tools/wc/wc.js | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/implement-shell-tools/wc/wc.js b/implement-shell-tools/wc/wc.js index dea5ad059..13e8c8574 100644 --- a/implement-shell-tools/wc/wc.js +++ b/implement-shell-tools/wc/wc.js @@ -1,18 +1,13 @@ const fs = require("fs"); -const args = process.argv.slice(2); +const files = process.argv.slice(2); -const file = args[0]; +for (const file of files) { + const content = fs.readFileSync(file, "utf8"); -const content = fs.readFileSync(file, "utf8"); + const lines = content.split("\n").length; + const words = content.trim().split(/\s+/).length; + const chars = content.length; -// count lines -const lines = content.split("\n").length; - -// count words -const words = content.trim().split(/\s+/).length; - -// count characters -const chars = content.length; - -console.log(lines, words, chars, file); \ No newline at end of file + console.log(lines, words, chars, file); +} \ No newline at end of file From e28760ff4bed0dc6958f97bf688617c302c9e2db Mon Sep 17 00:00:00 2001 From: SlimMicheals Date: Wed, 8 Apr 2026 00:03:12 +0200 Subject: [PATCH 09/10] Add wc flags -l, -w, -c --- implement-shell-tools/wc/wc.js | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/implement-shell-tools/wc/wc.js b/implement-shell-tools/wc/wc.js index 13e8c8574..ee89ff398 100644 --- a/implement-shell-tools/wc/wc.js +++ b/implement-shell-tools/wc/wc.js @@ -1,6 +1,14 @@ const fs = require("fs"); -const files = process.argv.slice(2); +const args = process.argv.slice(2); + +const showLines = args.includes("-l"); +const showWords = args.includes("-w"); +const showChars = args.includes("-c"); + +const files = args.filter( + (arg) => arg !== "-l" && arg !== "-w" && arg !== "-c" +); for (const file of files) { const content = fs.readFileSync(file, "utf8"); @@ -9,5 +17,13 @@ for (const file of files) { const words = content.trim().split(/\s+/).length; const chars = content.length; - console.log(lines, words, chars, file); + if (showLines) { + console.log(lines, file); + } else if (showWords) { + console.log(words, file); + } else if (showChars) { + console.log(chars, file); + } else { + console.log(lines, words, chars, file); + } } \ No newline at end of file From 7ec1b658a4f583320db1fde4bb4ea9a95c61714c Mon Sep 17 00:00:00 2001 From: SlimMicheals Date: Tue, 21 Apr 2026 15:55:23 +0200 Subject: [PATCH 10/10] Implement cowsay CLI using argparse and cowsay library --- implement-cowsay/cow.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 implement-cowsay/cow.py diff --git a/implement-cowsay/cow.py b/implement-cowsay/cow.py new file mode 100644 index 000000000..7aff7f3b9 --- /dev/null +++ b/implement-cowsay/cow.py @@ -0,0 +1,26 @@ +import argparse +import cowsay + + +def main(): + parser = argparse.ArgumentParser(description="Make animals say things") + parser.add_argument( + "--animal", + choices=cowsay.char_names, + default="cow", + help="The animal to be saying things." + ) + parser.add_argument( + "message", + nargs="+", + help="The message to say." + ) + + args = parser.parse_args() + message = " ".join(args.message) + + print(cowsay.get_output_string(args.animal, message)) + + +if __name__ == "__main__": + main() \ No newline at end of file