diff --git a/implement-shell-tools/cat/cat-commander.js b/implement-shell-tools/cat/cat-commander.js new file mode 100644 index 00000000..5cc5ffb2 --- /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 00000000..9ca8c442 --- /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 00000000..b1c28b2c --- /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) + + + + diff --git a/number-systems/README.md b/number-systems/README.md deleted file mode 100644 index 77a3bde9..00000000 --- a/number-systems/README.md +++ /dev/null @@ -1,65 +0,0 @@ -Do not use any tools or programming to solve these problems. Work it out yourself by hand, and fill in the answers. - -Do not convert any binary numbers to decimal when solving a question unless the question explicitly tells you to. - -The goal of these exercises is for you to gain an intuition for binary numbers. Using tools to solve the problems defeats the point. - -Convert the decimal number 14 to binary. -Answer: - -Convert the binary number 101101 to decimal: -Answer: - -Which is larger: 1000 or 0111? -Answer: - -Which is larger: 00100 or 01011? -Answer: - -What is 10101 + 01010? -Answer: - -What is 10001 + 10001? -Answer: - -What's the largest number you can store with 4 bits, if you want to be able to represent the number 0? -Answer: - -How many bits would you need in order to store the numbers between 0 and 255 inclusive? -Answer: - -How many bits would you need in order to store the numbers between 0 and 3 inclusive? -Answer: - -How many bits would you need in order to store the numbers between 0 and 1000 inclusive? -Answer: - -How can you test if a binary number is a power of two (e.g. 1, 2, 4, 8, 16, ...)? -Answer: - -Convert the decimal number 14 to hex. -Answer: - -Convert the decimal number 386 to hex. -Answer: - -Convert the hex number 386 to decimal. -Answer: - -Convert the hex number B to decimal. -Answer: - -If reading the byte 0x21 as a number, what decimal number would it mean? -Answer: - -If reading the byte 0x21 as an ASCII character, what character would it mean? -Answer: - -If reading the byte 0x21 as a greyscale colour, as described in "Approaches for Representing Colors and Images", what colour would it mean? -Answer: - -If reading the bytes 0xAA00FF as an RGB colour, as described in "Approaches for Representing Colors and Images", what colour would it mean? -Answer: - -If reading the bytes 0xAA00FF as a sequence of three one-byte decimal numbers, what decimal numbers would they be? -Answer: