diff --git a/implement-shell-tools/cat/my-cat.js b/implement-shell-tools/cat/my-cat.js new file mode 100755 index 000000000..47e1444de --- /dev/null +++ b/implement-shell-tools/cat/my-cat.js @@ -0,0 +1,41 @@ +#!/usr/bin/env node + +const fs = require("fs"); + +const args = process.argv.slice(2); + +let numberLines = false; +let numberNonEmpty = false; + +if (args[0] === "-n") { + numberLines = true; + args.shift(); +} else if (args[0] === "-b") { + numberNonEmpty = true; + args.shift(); +} +let count = 1; + +args.forEach((file) => { + const content = fs.readFileSync(file, "utf-8"); + const lines = content.split(/\r?\n/); + + + if (numberLines){ + lines.forEach((line) => { + console.log(`${count} ${line}`); + count++; + }); + } else if (numberNonEmpty){ + lines.forEach((line) => { + if (line !== "") { + console.log(`${count} ${line}`); + count++; + } else { + console.log(""); + } + }); +} else { +console.log(content); + } +}); diff --git a/implement-shell-tools/cat/my-cat.sh b/implement-shell-tools/cat/my-cat.sh new file mode 100755 index 000000000..7b9700803 --- /dev/null +++ b/implement-shell-tools/cat/my-cat.sh @@ -0,0 +1,42 @@ +#!/bin/bash + +set -euo pipefail + +number_lines=false +number_non_empty=false + +# check for flags +if [ "${1:-}" = "-n" ]; then + number_lines=true + shift +elif [ "${1:-}" = "-b" ]; then + number_non_empty=true + shift +fi + +count=1 + +# Loop through all files + +for file in "$@" +do + while IFS= read -r line + do + if [ "$number_lines" = true ]; then + echo "$count $line" + count=$((count+1)) + + else if [ "$number_non_empty" = true ]; then + if [ -n "$line" ]; then + echo "$count $line" + count=$((count+1)) + else + echo "" + fi + + else + echo "$line" + fi + fi + done < "$file" +done \ No newline at end of file diff --git a/implement-shell-tools/ls/my-ls.js b/implement-shell-tools/ls/my-ls.js new file mode 100755 index 000000000..8c3ecd812 --- /dev/null +++ b/implement-shell-tools/ls/my-ls.js @@ -0,0 +1,41 @@ +#!/usr/bin/env node + +const fs = require("node:fs"); +const path = require("node:path"); + +function parseArgs(args) { + let showAll = false; + let targetDir = "."; + + for (const arg of args) { + if (arg === "-a") { + showAll = true; + } else if (!arg.startsWith("-")) { + targetDir = arg; + } + } + + return { showAll, targetDir }; +} + +function listDirectory(dirPath, showAll) { + let files = fs.readdirSync(dirPath); + + if (!showAll) { + files = files.filter(file => !file.startsWith(".")); + } + + return files.sort(); +} + +function main() { + const args = process.argv.slice(2); + const { showAll, targetDir } = parseArgs(args); + + const files = listDirectory(targetDir, showAll); + console.log(files.join("\n")); +} + +main(); + + diff --git a/implement-shell-tools/ls/my-ls.sh b/implement-shell-tools/ls/my-ls.sh new file mode 100755 index 000000000..b44cbf072 --- /dev/null +++ b/implement-shell-tools/ls/my-ls.sh @@ -0,0 +1,34 @@ + #!/bin/bash + set -euo pipefail + +show_all=false + +# handle -a +if [ "${1:-}" = "-a" ]; then + show_all=true + shift +fi + +# directory (default current) + dir="." + + if [ "${1:-}" != "" ]; then + dir="$1" + fi + + #choose pattern + if [ "$show_all" = true ]; then + files="$dir"/.* + else + files="$dir"/* + fi + # loop + for file in $files + do + name="$(basename "$file")" + + if [ "$name" = "." ] || [ "$name" = ".." ]; then + continue + fi + echo "$name" + done \ No newline at end of file diff --git a/implement-shell-tools/wc/my-wc.js b/implement-shell-tools/wc/my-wc.js new file mode 100755 index 000000000..ccd2658bf --- /dev/null +++ b/implement-shell-tools/wc/my-wc.js @@ -0,0 +1,67 @@ +#!/usr/bin/env node + +const fs = require("node:fs"); + +function countFile(filePath) { + const content = fs.readFileSync(filePath, "utf8"); + + const lines = content.split("\n").length - 1; + const words = content.trim() ? content.trim().split(/\s+/).length : 0; + const chars = Buffer.byteLength(content, "utf8"); + + return { lines, words, chars }; +} + +function main() { + const args = process.argv.slice(2); + + let flag = null; + let files = []; + + for (const arg of args) { + if (arg === "-l" || arg === "-w" || arg === "-c") { + flag = arg; + } else { + files.push(arg); + } + } + + let totalLines = 0; + let totalWords = 0; + let totalChars = 0; + + for (const file of files) { + const { lines, words, chars } = countFile(file); + + totalLines += lines; + totalWords += words; + totalChars += chars; + + if (flag === "-l") { + console.log(`${lines} ${file}`); + } else if (flag === "-w") { + console.log(`${words} ${file}`); + } else if (flag === "-c") { + console.log(`${chars} ${file}`); + } else { + console.log(`${lines} ${words} ${chars} ${file}`); + } + } + + if (files.length > 1) { + if (flag === "-l") { + console.log(`${totalLines} total`); + } else if (flag === "-w") { + console.log(`${totalWords} total`); + } else if (flag === "-c") { + console.log(`${totalChars} total`); + } else { + console.log(`${totalLines} ${totalWords} ${totalChars} total`); + } + } +} + +main(); + + + diff --git a/implement-shell-tools/wc/my-wc.sh b/implement-shell-tools/wc/my-wc.sh new file mode 100755 index 000000000..067b2019f --- /dev/null +++ b/implement-shell-tools/wc/my-wc.sh @@ -0,0 +1,45 @@ +#!/bin/bash + +set -euo pipefail + +flag="all" + +if [ "${1:-}" = "-l" ]; then + flag="l" + shift +elif [ "${1:-}" = "-w" ]; then + flag="w" + shift +elif [ "${1:-}" = "-c" ]; then + flag="c" + shift +fi + +for file in "$@" +do + if [ -d "$file" ]; then + continue + fi + + lines=0 + words=0 + chars=0 + + while IFS= read -r line + do + lines=$((lines + 1)) + words=$((words + $(echo "$line" | wc -w))) + chars=$((chars + ${#line} + 1)) + done <"$file" + + if [ "$flag" = "l" ]; then + echo "$lines $file" + elif [ "$flag" = "w" ]; then + echo "$words $file" + elif [ "$flag" = "c" ]; then + echo "$chars $file" + else + echo "$lines $words $chars $file" + fi +done +