diff --git a/implement-shell-tools/cat/cat.js b/implement-shell-tools/cat/cat.js new file mode 100644 index 000000000..e2f05ea15 --- /dev/null +++ b/implement-shell-tools/cat/cat.js @@ -0,0 +1,48 @@ +import { promises as fs } from "node:fs"; + +// get all command line arguments after "node cat.js" - like -n or -b +const args = process.argv.slice(2); + +// put them in variables +const showAllNumbers = args.includes("-n"); +const showNonEmptyNumbers = args.includes("-b"); + +// getting the paths of files +const paths = args.filter(arg => arg !== "-n" && arg !== "-b"); + +// helper: mimic real cat line number formatting +const padLineNumber = (num) => String(num).padStart(6, " "); + +// loop over each file +for (const path of paths) { + try { + // read file as text + const content = await fs.readFile(path, "utf-8"); + + // split them into lines + const lines = content.split("\n"); + + let lineNumber = 1; // tracks line numbers for -b and -n + + for (const line of lines) { + if (showNonEmptyNumbers) { + // -b: number only non-empty lines + if (line !== "") { + console.log(`${padLineNumber(lineNumber)} ${line}`); + lineNumber++; + } else { + console.log(line); // shows empty line with no number + } + } else if (showAllNumbers) { + // -n: number all lines + console.log(`${padLineNumber(lineNumber)} ${line}`); + lineNumber++; + } else { + // no flags: just print line + console.log(line); + } + } + } catch (err) { + console.error(`Error reading file "${path}": ${err.message}`); + } +} \ No newline at end of file diff --git a/implement-shell-tools/ls/ls.js b/implement-shell-tools/ls/ls.js new file mode 100644 index 000000000..e4978f897 --- /dev/null +++ b/implement-shell-tools/ls/ls.js @@ -0,0 +1,41 @@ +import { promises as fs } from "node:fs"; + +//getting all commands +const args = process.argv.slice(2); + +const showOnePerLine = args.includes("-1"); +const showAllFilesWithHidden = args.includes("-a"); + +//current path +const path = args.find(arg => !arg.startsWith("-")) || "."; +// if we do console.log("path=> ",path," args=> " ,args); it will give us this =>: path=> sample-files args=> [ '-1', '-a', 'sample-files' ] + +try { + const direc = await fs.readdir(path); + + // handle hidden files (-a flag controls this) + let files = direc; + + if (!showAllFilesWithHidden) { + files = files.filter(file => !file.startsWith(".")); + } + + // one file per line + if (showOnePerLine) { + files.forEach(file => { + console.log(file); + }); + } + + // default behavior: also one per line (simple version of ls) + else { + files.forEach(file => { + console.log(file); + }); + } + +} catch (err) { + console.error(`Error reading directory "${path}": ${err.message}`); +} + + diff --git a/implement-shell-tools/wc/README.md b/implement-shell-tools/wc/README.md index bd76b655a..98c2494d7 100644 --- a/implement-shell-tools/wc/README.md +++ b/implement-shell-tools/wc/README.md @@ -14,4 +14,4 @@ It must act the same as `wc` would, if run from the directory containing this RE Matching any additional behaviours or flags are optional stretch goals. -We recommend you start off supporting no flags for one file, then add support for multiple files, then add support for the flags. +We recommend you start off supporting no flags for one file, then add support for multiple files, then add support for the flags \ No newline at end of file diff --git a/implement-shell-tools/wc/wc.js b/implement-shell-tools/wc/wc.js new file mode 100644 index 000000000..dfd403507 --- /dev/null +++ b/implement-shell-tools/wc/wc.js @@ -0,0 +1,55 @@ +import { promises as fs } from "node:fs"; + +const args = process.argv.slice(2); + +const showLines = args.includes("-l"); +const showWords = args.includes("-w"); +const showChars = args.includes("-c"); +let paths = args.filter(arg => !arg.startsWith("-")); +if (paths.length === 0) paths = ["."]; + +// helper for formatting like real wc +const pad = (n) => String(n).padStart(8, " "); + +let totalLines = 0; +let totalWords = 0; +let totalChars = 0; + +for (const path of paths) { + try { + const content = await fs.readFile(path, "utf-8"); + + const lines = content.split("\n").length; + const words = content.split(/\s+/).filter(Boolean).length; + const chars = content.length; + + totalLines += lines; + totalWords += words; + totalChars += chars; + + } catch (err) { + console.error(`Error reading file "${path}": ${err.message}`); + } + +} +if (showLines) { + console.log("lines:", totalLines); +} + +if (showWords) { + console.log("words:", totalWords); +} + +if (showChars) { + console.log("chars:", totalChars); +} + + +// default output when no flags +if (!showLines && !showWords && !showChars) { + console.log( + `${pad(totalLines)}\t${pad(totalWords)}\t${pad(totalChars)}\ttotal` + ); +} + +