diff --git a/implement-shell-tools/cat/cat.js b/implement-shell-tools/cat/cat.js new file mode 100644 index 00000000..0beafdf0 --- /dev/null +++ b/implement-shell-tools/cat/cat.js @@ -0,0 +1,32 @@ +import process from "node:process"; +import { promises as fs } from "node:fs"; + +const arrArgv = process.argv.slice(2); + +const numberLines = arrArgv.includes("-n"); +const numberNonemptyLines = arrArgv.includes("-b"); + +const nonFlagArrArgv = arrArgv.filter((arr) => !arr.startsWith("-")); + +let number = 1; + +for (let file of nonFlagArrArgv) { + const content = await fs.readFile(file, "utf-8"); + + const linedText = content.split("\n"); + + const formatLines = (line) => { + return `${String(number++).padStart(3)} ${line}`; + }; + + const numbered = linedText.map((line) => { + if (numberNonemptyLines && line.trim() === "") { + return line; + } + if (numberNonemptyLines || numberLines) { + return formatLines(line); + } + return line; + }); + console.log(numbered.join("\n")); +} diff --git a/implement-shell-tools/ls/ls.js b/implement-shell-tools/ls/ls.js new file mode 100644 index 00000000..91060fbb --- /dev/null +++ b/implement-shell-tools/ls/ls.js @@ -0,0 +1,50 @@ +import process from "node:process"; +import { promises as fs } from "node:fs"; +import path from "node:path"; + +const arrArgv = process.argv.slice(2); + +const longFormat = arrArgv.includes("-l"); +const showHidden = arrArgv.includes("-a"); + +let paths = arrArgv.filter((argv) => !argv.startsWith("-")); +if (paths.length === 0) paths = ["."]; + +const printWholeList = (stats, name) => { + const permissions = (stats.mode & 0o777).toString(8); + const sizeFile = stats.size; + const owner = stats.uid; + const group = stats.gid; + const timeMod = stats.mtime.toLocaleString(); + + console.log( + `${permissions}, ${owner}, ${group}, ${sizeFile}, ${timeMod}, ${name}` + ); +}; +for (const listFile of paths) { + const status = await fs.stat(listFile); + if (status.isFile()) { + if (longFormat) { + printWholeList(status, listFile); + } else { + console.log(listFile); + } + } else { + let files = await fs.readdir(listFile, { withFileTypes: true }); + + if (!showHidden) { + files = files.filter((file) => !file.name.startsWith(".")); + } + + for (const file of files) { + const wholePath = path.join(listFile, file.name); + + if (longFormat) { + const statusFile = await fs.stat(wholePath); + printWholeList(statusFile, file.name); + } else { + console.log(file.name); + } + } + } +} diff --git a/implement-shell-tools/wc/wc.js b/implement-shell-tools/wc/wc.js new file mode 100644 index 00000000..2648d62d --- /dev/null +++ b/implement-shell-tools/wc/wc.js @@ -0,0 +1,38 @@ +import process from "node:process"; +import { promises as fs } from "node:fs"; + +const arrArgv = process.argv.slice(2); + +const lines = arrArgv.includes("-l"); +const words = arrArgv.includes("-w"); +const bytes = arrArgv.includes("-c"); + +const noFlags = !lines && !words && !bytes; + +const paths = arrArgv.filter((argv) => !argv.startsWith("-")); + +for (let path of paths) { + const context = await fs.readFile(path, "utf-8"); + + const countLines = context.split(/\r?\n/).length; + const countWords = context.split(/\s+/).length; + const countBytes = Buffer.byteLength(context, "utf-8"); + + let startInput = ""; + + if (noFlags || lines) { + startInput += `${countLines} `; + } + + if (noFlags || words) { + startInput += `${countWords} `; + } + + if (noFlags || bytes) { + startInput += `${countBytes} `; + } + + startInput += path; + + console.log(startInput); +}