diff --git a/implement-shell-tools/cat/cat.js b/implement-shell-tools/cat/cat.js new file mode 100644 index 000000000..2688c3eab --- /dev/null +++ b/implement-shell-tools/cat/cat.js @@ -0,0 +1,51 @@ +import { readFile } from "node:fs/promises"; +import process from "node:process"; +import { parseArgs } from "node:util"; + +const { values, positionals: files } = parseArgs({ + args: process.argv.slice(2), + options: { + number: { + type: "boolean", + short: "n", + }, + numberNonBlank: { + type: "boolean", + short: "b", + }, + }, + allowPositionals: true, +}); + +const showLineNumbers = values.number ?? false; +const numberNonBlankLines = values.numberNonBlank ?? false; + +let lineNumber = 1; + +for (const file of files) { + try { + const content = await readFile(file, "utf-8"); + + const lines = content.split("\n"); + + if (numberNonBlankLines) { + for (const line of lines) { + if (line !== "") { + console.log(`${lineNumber} ${line}`); + lineNumber++; + } else { + console.log(""); + } + } + } else if (showLineNumbers) { + for (const line of lines) { + console.log(`${lineNumber} ${line}`); + lineNumber++; + } + } else { + process.stdout.write(content); + } + } catch (err) { + console.error(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..6eac11714 --- /dev/null +++ b/implement-shell-tools/ls/ls.js @@ -0,0 +1,51 @@ +import { readdir, stat } from "node:fs/promises"; +import process from "node:process"; + +const argv = process.argv.slice(2); + +let onePerLine = false; +let showAll = false; +const paths = []; + +for (const arg of argv) { + if (arg === "-1") { + onePerLine = true; + } else if (arg === "-a") { + showAll = true; + } else { + paths.push(arg); + } +} + +if (paths.length === 0) { + paths.push("."); +} + +for (const path of paths) { + try { + const info = await stat(path); + + if (info.isDirectory()) { + let files = await readdir(path); + + if (!showAll) { + files = files.filter((file) => !file.startsWith(".")); + } + + if (onePerLine) { + for (const file of files) { + console.log(file); + } + } else { + for (const file of files) { + process.stdout.write(`${file} `); + } + process.stdout.write("\n"); + } + } else { + console.log(path); + } + } catch (err) { + console.error(err.message); + } +} \ 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..3bc5e0237 --- /dev/null +++ b/implement-shell-tools/wc/wc.js @@ -0,0 +1,85 @@ +import { readFile } from "node:fs/promises"; +import process from "node:process"; +import { parseArgs } from "node:util"; + +const { values, positionals: files } = parseArgs({ + args: process.argv.slice(2), + + options: { + lines: { + type: "boolean", + short: "l", + }, + + words: { + type: "boolean", + short: "w", + }, + + bytes: { + type: "boolean", + short: "c", + }, + }, + + allowPositionals: true, +}); + +const countLines = values.lines ?? false; +const countWords = values.words ?? false; +const countBytes = values.bytes ?? false; + +function printCounts(lines, words, bytes, label) { + const parts = []; + + if (countLines) { + parts.push(lines); + } + + if (countWords) { + parts.push(words); + } + + if (countBytes) { + parts.push(bytes); + } + + if (!countLines && !countWords && !countBytes) { + parts.push(lines, words, bytes); + } + + const output = parts.map((value) => String(value).padStart(8)).join(""); + + process.stdout.write(`${output} ${label}\n`); +} + +let totalWords = 0; +let totalLines = 0; +let totalBytes = 0; + +for (const file of files) { + try { + const content = await readFile(file, "utf-8"); + const arrayOfLines = content.split("\n"); + const arrayOfWords = content.trim().split(/\s+/) + const bytes = Buffer.byteLength(content, "utf-8"); + const lines = arrayOfLines.length -1; + const words = arrayOfWords.length; + totalLines += lines; + totalBytes += bytes; + totalWords += words; + printCounts(lines, words, bytes, file); + + } catch (err) { + console.error(err.message); + } +} + +if (files.length > 1) { + printCounts( + totalLines, + totalWords, + totalBytes, + "total" + ); +} \ No newline at end of file