diff --git a/implement-shell-tools/cat/cat-commander.js b/implement-shell-tools/cat/cat-commander.js new file mode 100644 index 000000000..5cc5ffb28 --- /dev/null +++ b/implement-shell-tools/cat/cat-commander.js @@ -0,0 +1,56 @@ +import { program } from "commander"; +import { promises as fs } from "node:fs"; +import process from "node:process"; + +program + .name("read-files-content") + .description("Read the content of a file (simulating cat command)") + .option("-n, --number","Number of lines") + .option("-b","Number of no-blanks lines") + .argument("","The file path to process"); //file + +program.parse(); + +const argv = program.args; + +if (argv.length === 0) { + console.error(`Expected file path(s),passed but got ${argv.length}.`); + process.exit(1); +} + +//const path = argv[0]; +for (const path of argv){ + const option = program.opts(); + const content = await fs.readFile(path, "utf-8"); + if (option.number){ + // split content + let lines = content.split(/\n/); + // removes last line + if (lines[lines.length - 1] === ""){ + lines = lines.slice(0,-1); + } + lines + .map((line,index) => `${(index + 1).toString().padStart(6)}\t${line}`) + .forEach(line => console.log(line)) + + } else if (option.b){ + let lines = content.split("\n"); + let linesCounter = 0; + if (lines[lines.length - 1] === ""){ + lines = lines.slice(0,-1); + } + lines + .map((line) => { + if (line.trim().length > 0) { + linesCounter++; + return `${linesCounter.toString().padStart(6)}\t${line}` + }else{ + return `${line}` + }} + ) + .forEach(line => console.log(line)) + }else { + const output = content.endsWith("\n") ? content.slice(0,-1) : content; + console.log(output); + } +} diff --git a/implement-shell-tools/ls/ls-commander.js b/implement-shell-tools/ls/ls-commander.js new file mode 100644 index 000000000..9ca8c4421 --- /dev/null +++ b/implement-shell-tools/ls/ls-commander.js @@ -0,0 +1,36 @@ +import { program } from "commander"; +import { promises as fs } from "node:fs"; +import process from "node:process"; + +program + .name("list-files") + .description("List files in a directory") + .option("-1", "Show line by line") + .option("-a, --all", "Show hidden files") + .argument("[paths...]", "The directory paths",["."]); + +program.parse(); + +const argv = program.args; + +if (argv.length != 1){ + console.error(`Expected exactly 1 argument (a path) to be passed but got ${argv.length}`); + process.exit(1); +} +const dirPath = argv[0]; +const options = program.opts(); + +const entries = await fs.readdir(dirPath) + +const listFiles = entries.map((entry) => `${entry.padStart(6)}` ) +const noHidden = listFiles.filter(name => !name.startsWith('.')); + +if (options.all && options[1]){ + console.log(listFiles.join('\n')); +} else if (options.all) { + console.log(listFiles.join(' ')); +} else if (options[1]){ + console.log(noHidden.join('\n')); +} else { + console.log(noHidden.join(' ')); +} diff --git a/implement-shell-tools/wc/wc-commander.js b/implement-shell-tools/wc/wc-commander.js new file mode 100644 index 000000000..b1c28b2cc --- /dev/null +++ b/implement-shell-tools/wc/wc-commander.js @@ -0,0 +1,61 @@ +import {program} from "commander"; +import { promises as fs } from "node:fs"; +import process from "node:process"; +import { glob } from "glob"; + +program + .name("content counter") + .description("Counts lines, words, or characters in a file or files of a directory.") + .option("-l,--lines","Options for l:Lines.") + .option("-w,--words","Options for w:words.") + .option("-c","Options for c:characters.") + .argument("","The file or directory to process"); + +program.parse(); + +const argv = program.args; + +const options = program.opts(); + +const result = []; +let totalLines = 0; +let totalWords = 0; +let totalChars = 0; + +for (const file of argv){ + + //1. Read each file + + const content = await fs.readFile(file,"utf-8"); + // 2. calculate values + const lines = content.split(/\n/g).length - 1 ; + const words = content.trim().split(/\s+/).length; + const chars = content.split("").length; + // variable to pile up final line results according options + const thisLine = []; + if (options.lines){ thisLine.push(lines.toString().padStart(8)) }; + if (options.words){ thisLine.push(words.toString().padStart(8)) }; + if (options.c){ thisLine.push(chars.toString().padStart(8)) }; + if (!options.lines && !options.words && !options.c){ thisLine.push(lines.toString().padStart(8),words.toString().padStart(8),chars.toString().padStart(8)) }; + result.push(`${thisLine.join("")} ${file}`) + // 3. add results + // variables to accumulate the total + totalLines += lines; + totalWords += words; + totalChars += chars; +// 4. add total results if several files +} +if (argv.length>1){ + const finalLine = []; + finalLine.push(totalLines.toString().padStart(8)), + finalLine.push(totalWords.toString().padStart(8)), + finalLine.push(totalChars.toString().padStart(8)); + result.push(`${finalLine.join("")} total`) +} +// 5. show results +const output = result.join('\n'); +console.log(output) + + + +