From 1fa12213d0b2a43865e4e5d15719383de5fcc496 Mon Sep 17 00:00:00 2001 From: Faithy4444 Date: Sun, 6 Jul 2025 19:18:25 +0200 Subject: [PATCH 1/9] script 1 to 3 --- individual-shell-tools/ls/script-01.sh | 1 + individual-shell-tools/ls/script-02.sh | 1 + 2 files changed, 2 insertions(+) diff --git a/individual-shell-tools/ls/script-01.sh b/individual-shell-tools/ls/script-01.sh index 241b62f5e..081f2c7c2 100755 --- a/individual-shell-tools/ls/script-01.sh +++ b/individual-shell-tools/ls/script-01.sh @@ -13,3 +13,4 @@ fi # TODO: Write a command to list the files and folders in this directory. # The output should be a list of names including child-directory, script-01.sh, script-02.sh, and more. +ls \ No newline at end of file diff --git a/individual-shell-tools/ls/script-02.sh b/individual-shell-tools/ls/script-02.sh index d0a5a10f4..48c16842c 100755 --- a/individual-shell-tools/ls/script-02.sh +++ b/individual-shell-tools/ls/script-02.sh @@ -4,3 +4,4 @@ set -euo pipefail # TODO: Write a command which lists all of the files in the directory named child-directory. # The output should be a list of names: helper-1.txt, helper-2.txt, helper-3.txt. +ls chile \ No newline at end of file From c19108ddb5cd83b0c4d541bd6a40cd4ed6719add Mon Sep 17 00:00:00 2001 From: Faithy4444 Date: Sun, 27 Jul 2025 21:10:08 +0200 Subject: [PATCH 2/9] cat command --- implement-shell-tools/cat/cat.mjs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 implement-shell-tools/cat/cat.mjs diff --git a/implement-shell-tools/cat/cat.mjs b/implement-shell-tools/cat/cat.mjs new file mode 100644 index 000000000..237db6eea --- /dev/null +++ b/implement-shell-tools/cat/cat.mjs @@ -0,0 +1,17 @@ +import { program } from "commander"; +import{promises as fs} from "node:fs"; +import process from "node:process"; + +program +.name("cat") +.description("displays the contents of a file") +.option('-n, --number', 'Number all output lines') +.argument(""); + +program.parse(); + +const args = program.args + +const path = args[0] +const content = await fs.readFile(path, "utf-8"); +console.log(content) \ No newline at end of file From 6dea2a314c451ce9a36c4ad7a82901bdd6da7ba8 Mon Sep 17 00:00:00 2001 From: Faithy4444 Date: Mon, 28 Jul 2025 13:41:23 +0200 Subject: [PATCH 3/9] cat.mjs with flags --- implement-shell-tools/cat/cat.mjs | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/implement-shell-tools/cat/cat.mjs b/implement-shell-tools/cat/cat.mjs index 237db6eea..b409f686d 100644 --- a/implement-shell-tools/cat/cat.mjs +++ b/implement-shell-tools/cat/cat.mjs @@ -6,12 +6,35 @@ program .name("cat") .description("displays the contents of a file") .option('-n, --number', 'Number all output lines') +.option("-b, --number-nonblank", 'Number non-blank output lines only') .argument(""); program.parse(); -const args = program.args + +const args = program.args; +const opts = program.opts(); + +if (args.length === 0) { + console.error("Error: Missing argument."); + program.help(); +} const path = args[0] const content = await fs.readFile(path, "utf-8"); -console.log(content) \ No newline at end of file + const lines = content.split('\n'); +if(opts.number){ + for (let i = 0; i < lines.length; i++) { + console.log(`${i + 1}\t${lines[i]}`); + } + }else if (opts.numberNonblank) { + let lineNumber = 1; + for (let i = 0; i < lines.length; i++) { + if (lines[i].trim() !== '') { + console.log(`${lineNumber.toString().padStart(6)}\t${lines[i]}`); + lineNumber++; + } + } + }else console.log(content) + + \ No newline at end of file From 2c78b432c69eef7f80c6390cf341f8ac186878ad Mon Sep 17 00:00:00 2001 From: Faithy4444 Date: Mon, 28 Jul 2025 20:04:27 +0200 Subject: [PATCH 4/9] ls command with flags --- implement-shell-tools/ls/ls.mjs | 34 +++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 implement-shell-tools/ls/ls.mjs diff --git a/implement-shell-tools/ls/ls.mjs b/implement-shell-tools/ls/ls.mjs new file mode 100644 index 000000000..5f870d062 --- /dev/null +++ b/implement-shell-tools/ls/ls.mjs @@ -0,0 +1,34 @@ +import {program} from "commander"; +import {promises as fs} from "node:fs"; +import { readdir } from "node:fs"; + +program +.name("ls") +.description("displays files in a directory") +.option("-1, --one", "displays each file in its own line") +.option("-a, --all", "displays all files including hidden files") +.arguments("") + +await program.parseAsync(); + +const opts = program.opts(); +const args = program.args; + +if (args.length === 0) { + console.error("Error: Missing argument."); + program.help(); +} + +const path = args[0]; +const files = await fs.readdir(path, "utf-8"); + +let visibleFiles = files; +if (!opts.all) { + visibleFiles = files.filter(file => !file.startsWith('.')); +} + +if (opts.one) { + visibleFiles.forEach(file => console.log(file)); +} else { + console.log(visibleFiles.join(' ')); +} \ No newline at end of file From 84aee2dd10124a7f5ad1a58029ed379f884fd899 Mon Sep 17 00:00:00 2001 From: Faithy4444 Date: Tue, 29 Jul 2025 11:17:58 +0200 Subject: [PATCH 5/9] wc command complete --- implement-shell-tools/wc/wc.mjs | 51 +++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 implement-shell-tools/wc/wc.mjs diff --git a/implement-shell-tools/wc/wc.mjs b/implement-shell-tools/wc/wc.mjs new file mode 100644 index 000000000..910225053 --- /dev/null +++ b/implement-shell-tools/wc/wc.mjs @@ -0,0 +1,51 @@ +import {program} from "commander"; +import{promises as fs} from "node:fs"; + +program +.name("wc") +.description("counts lines, words, and bytes") +.option("-l, --line", "counts number of lines in the file") +.option("-w, --words", "counts number of words in the file") +.option("-c, --bytes", "counts number of bytes in the file") +.argument("") + +program.parse(); + +const args= program.args; +const opts = program.opts(); + +if(args.length === 0){ + console.error("Error: Missing argument."); + program.help(); +} + +const path = args[0]; +const content = await fs.readFile(path, "utf-8") + + +// function to count the number of lines in a files +function countLines(content){ +const lines = content.split(/\r?\n/) +return lines.length +} + +//function to count the words +function countWords(content){ + const words = content.trim().split(/\s+/); + return words.length +} + +//function to count the bytes +function countBytes(content){ + return Buffer.byteLength(content, "utf-8"); +} + +if (opts.line){ + console.log(countLines(content)) +}else if(opts.words){console.log(countWords(content), path)} +else if(opts.bytes){console.log(countBytes(content), path)} +else{ + console.log(countLines(content), countWords(content), countBytes(content), path) +} + + From a3656024fbed94251b740c5ed0b895a02367b532 Mon Sep 17 00:00:00 2001 From: Faithy4444 Date: Tue, 29 Jul 2025 11:38:02 +0200 Subject: [PATCH 6/9] all done and refactored --- implement-shell-tools/cat/cat.mjs | 6 +++--- implement-shell-tools/ls/ls.mjs | 7 +++---- implement-shell-tools/wc/wc.mjs | 30 +++++++++++++++++------------- 3 files changed, 23 insertions(+), 20 deletions(-) diff --git a/implement-shell-tools/cat/cat.mjs b/implement-shell-tools/cat/cat.mjs index b409f686d..421a94bab 100644 --- a/implement-shell-tools/cat/cat.mjs +++ b/implement-shell-tools/cat/cat.mjs @@ -1,12 +1,12 @@ import { program } from "commander"; import{promises as fs} from "node:fs"; -import process from "node:process"; + program .name("cat") .description("displays the contents of a file") -.option('-n, --number', 'Number all output lines') -.option("-b, --number-nonblank", 'Number non-blank output lines only') +.option("-n, --number", "Number all output lines") +.option("-b, --number-nonblank", "Number non-blank output lines only") .argument(""); program.parse(); diff --git a/implement-shell-tools/ls/ls.mjs b/implement-shell-tools/ls/ls.mjs index 5f870d062..b426b9c3a 100644 --- a/implement-shell-tools/ls/ls.mjs +++ b/implement-shell-tools/ls/ls.mjs @@ -1,6 +1,5 @@ import {program} from "commander"; import {promises as fs} from "node:fs"; -import { readdir } from "node:fs"; program .name("ls") @@ -20,15 +19,15 @@ if (args.length === 0) { } const path = args[0]; -const files = await fs.readdir(path, "utf-8"); +const files = await fs.readdir(path); let visibleFiles = files; if (!opts.all) { - visibleFiles = files.filter(file => !file.startsWith('.')); + visibleFiles = files.filter(file => !file.startsWith(".")); } if (opts.one) { visibleFiles.forEach(file => console.log(file)); } else { - console.log(visibleFiles.join(' ')); + console.log(visibleFiles.join(" ")); } \ No newline at end of file diff --git a/implement-shell-tools/wc/wc.mjs b/implement-shell-tools/wc/wc.mjs index 910225053..80e2bbcb2 100644 --- a/implement-shell-tools/wc/wc.mjs +++ b/implement-shell-tools/wc/wc.mjs @@ -20,19 +20,19 @@ if(args.length === 0){ } const path = args[0]; -const content = await fs.readFile(path, "utf-8") +const content = await fs.readFile(path, "utf-8"); // function to count the number of lines in a files function countLines(content){ -const lines = content.split(/\r?\n/) -return lines.length +const lines = content.split(/\r?\n/); +return lines.length; } //function to count the words function countWords(content){ const words = content.trim().split(/\s+/); - return words.length + return words.length; } //function to count the bytes @@ -40,12 +40,16 @@ function countBytes(content){ return Buffer.byteLength(content, "utf-8"); } -if (opts.line){ - console.log(countLines(content)) -}else if(opts.words){console.log(countWords(content), path)} -else if(opts.bytes){console.log(countBytes(content), path)} -else{ - console.log(countLines(content), countWords(content), countBytes(content), path) -} - - +const lines = countLines(content); +const words = countWords(content); +const bytes = countBytes(content); + +if (opts.line) { + console.log(lines); +} else if (opts.words) { + console.log(words, path); +} else if (opts.bytes) { + console.log(bytes, path); +} else { + console.log(lines, words, bytes, path); +} \ No newline at end of file From d709f3b216e6ebbd5e58005686970e58ebffcfd3 Mon Sep 17 00:00:00 2001 From: Faithy4444 Date: Thu, 23 Oct 2025 03:26:10 +0200 Subject: [PATCH 7/9] cat command fixed --- implement-shell-tools/cat/cat.mjs | 43 ++++++++++++++++++------------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/implement-shell-tools/cat/cat.mjs b/implement-shell-tools/cat/cat.mjs index 421a94bab..b8ffa4d7b 100644 --- a/implement-shell-tools/cat/cat.mjs +++ b/implement-shell-tools/cat/cat.mjs @@ -7,7 +7,7 @@ program .description("displays the contents of a file") .option("-n, --number", "Number all output lines") .option("-b, --number-nonblank", "Number non-blank output lines only") -.argument(""); +.argument(""); program.parse(); @@ -20,21 +20,28 @@ if (args.length === 0) { program.help(); } -const path = args[0] -const content = await fs.readFile(path, "utf-8"); - const lines = content.split('\n'); -if(opts.number){ - for (let i = 0; i < lines.length; i++) { - console.log(`${i + 1}\t${lines[i]}`); - } - }else if (opts.numberNonblank) { - let lineNumber = 1; - for (let i = 0; i < lines.length; i++) { - if (lines[i].trim() !== '') { - console.log(`${lineNumber.toString().padStart(6)}\t${lines[i]}`); - lineNumber++; +let globalLineNumber = 1; + +for (const path of args) { + try { + const content = await fs.readFile(path, "utf-8"); + const lines = content.split('\n'); + + if (opts.number) { + lines.forEach((line, idx) => { + console.log(`${idx + 1}\t${line}`); + }); + } else if (opts.numberNonblank) { + for (const line of lines) { + if (line.trim() !== '') { + console.log(`${globalLineNumber}\t${line}`); + globalLineNumber++; } - } - }else console.log(content) - - \ No newline at end of file + } + } else { + console.log(content); + } + } catch (err) { + console.error(`Error reading file "${path}": ${err.message}`); + } +} \ No newline at end of file From 754587f1f2e9c1b9080c714c55424a5a42e46c56 Mon Sep 17 00:00:00 2001 From: Faithy4444 Date: Thu, 23 Oct 2025 03:28:49 +0200 Subject: [PATCH 8/9] ls simplified --- implement-shell-tools/ls/ls.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/implement-shell-tools/ls/ls.mjs b/implement-shell-tools/ls/ls.mjs index b426b9c3a..04f34eb65 100644 --- a/implement-shell-tools/ls/ls.mjs +++ b/implement-shell-tools/ls/ls.mjs @@ -27,7 +27,7 @@ if (!opts.all) { } if (opts.one) { - visibleFiles.forEach(file => console.log(file)); + visibleFiles.forEach(console.log); } else { console.log(visibleFiles.join(" ")); } \ No newline at end of file From 0886956303306d8865ef0c0b6bcc55e3989a4dca Mon Sep 17 00:00:00 2001 From: Faithy4444 Date: Thu, 23 Oct 2025 03:37:08 +0200 Subject: [PATCH 9/9] wc looping version --- implement-shell-tools/wc/wc.mjs | 73 ++++++++++++++++++++------------- 1 file changed, 45 insertions(+), 28 deletions(-) diff --git a/implement-shell-tools/wc/wc.mjs b/implement-shell-tools/wc/wc.mjs index 80e2bbcb2..b6df2e47b 100644 --- a/implement-shell-tools/wc/wc.mjs +++ b/implement-shell-tools/wc/wc.mjs @@ -7,7 +7,7 @@ program .option("-l, --line", "counts number of lines in the file") .option("-w, --words", "counts number of words in the file") .option("-c, --bytes", "counts number of bytes in the file") -.argument("") +.argument("") program.parse(); @@ -19,37 +19,54 @@ if(args.length === 0){ program.help(); } -const path = args[0]; -const content = await fs.readFile(path, "utf-8"); +const countLines = content => content.split(/\r?\n/).length; +const countWords = content => content.trim().split(/\s+/).filter(Boolean).length; +const countBytes = content => Buffer.byteLength(content, "utf-8"); +// store totals for multiple files +let totalLines = 0; +let totalWords = 0; +let totalBytes = 0; -// function to count the number of lines in a files -function countLines(content){ -const lines = content.split(/\r?\n/); -return lines.length; -} +for (const path of args) { + try { + const content = await fs.readFile(path, "utf-8"); -//function to count the words -function countWords(content){ - const words = content.trim().split(/\s+/); - return words.length; -} + const lines = countLines(content); + const words = countWords(content); + const bytes = countBytes(content); + + totalLines += lines; + totalWords += words; + totalBytes += bytes; + + // collect counts based on options + const output = []; + if (opts.line) output.push(lines); + if (opts.words) output.push(words); + if (opts.bytes) output.push(bytes); -//function to count the bytes -function countBytes(content){ - return Buffer.byteLength(content, "utf-8"); + // if no options are passed, print all + if (!opts.line && !opts.words && !opts.bytes) { + output.push(lines, words, bytes); + } + + console.log(...output, path); + } catch (err) { + console.error(`Error reading file "${path}": ${err.message}`); + } } -const lines = countLines(content); -const words = countWords(content); -const bytes = countBytes(content); - -if (opts.line) { - console.log(lines); -} else if (opts.words) { - console.log(words, path); -} else if (opts.bytes) { - console.log(bytes, path); -} else { - console.log(lines, words, bytes, path); +// print totals if more than one file +if (args.length > 1) { + const totalOutput = []; + if (opts.line) totalOutput.push(totalLines); + if (opts.words) totalOutput.push(totalWords); + if (opts.bytes) totalOutput.push(totalBytes); + + if (!opts.line && !opts.words && !opts.bytes) { + totalOutput.push(totalLines, totalWords, totalBytes); + } + + console.log(...totalOutput, "total"); } \ No newline at end of file