From 1576d23673c905182f65c30e60b937f6f83676b6 Mon Sep 17 00:00:00 2001 From: enjoy15 Date: Sat, 21 Mar 2026 12:22:03 +0000 Subject: [PATCH 1/3] complete cat excercise --- implement-shell-tools/cat/cat.js | 60 ++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100755 implement-shell-tools/cat/cat.js diff --git a/implement-shell-tools/cat/cat.js b/implement-shell-tools/cat/cat.js new file mode 100755 index 000000000..5005eed7e --- /dev/null +++ b/implement-shell-tools/cat/cat.js @@ -0,0 +1,60 @@ +#!/usr/bin/env node + +const fs = require('fs'); +const path = require('path'); + +function cat(files, options) { + let lineNumber = 1; + + files.forEach((file) => { + const filePath = path.resolve(file); + + try { + const data = fs.readFileSync(filePath, 'utf8'); + const lines = data.split('\n'); + + lines.forEach((line) => { + if (options.numberNonEmpty && line.trim()) { + console.log(`${lineNumber}\t${line}`); + lineNumber++; + } else if (options.numberLines) { + console.log(`${lineNumber}\t${line}`); + lineNumber++; + } else { + console.log(line); + } + }); + } catch (err) { + console.error(`cat: ${file}: No such file or directory`); + } + }); +} + +function main() { + const args = process.argv.slice(2); + const options = { + numberLines: false, + numberNonEmpty: false, + }; + + const files = []; + + args.forEach((arg) => { + if (arg === '-n') { + options.numberLines = true; + } else if (arg === '-b') { + options.numberNonEmpty = true; + } else { + files.push(arg); + } + }); + + if (files.length === 0) { + console.error('Usage: node cat.js [-n | -b] ...'); + process.exit(1); + } + + cat(files, options); +} + +main(); \ No newline at end of file From 34fe1d09e26f469a2df3c27364a6d37b4aff91b3 Mon Sep 17 00:00:00 2001 From: enjoy15 Date: Sat, 21 Mar 2026 12:43:06 +0000 Subject: [PATCH 2/3] complete ls exercise --- implement-shell-tools/ls/ls.js | 44 ++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 implement-shell-tools/ls/ls.js diff --git a/implement-shell-tools/ls/ls.js b/implement-shell-tools/ls/ls.js new file mode 100644 index 000000000..056213466 --- /dev/null +++ b/implement-shell-tools/ls/ls.js @@ -0,0 +1,44 @@ +#!/usr/bin/env node + +const fs = require('fs'); +const path = require('path'); + +function listFiles(directory, options) { + try { + const files = fs.readdirSync(directory, { withFileTypes: true }); + + files.forEach((file) => { + if (!options.all && file.name.startsWith('.')) { + return; // Skip hidden files unless -a is specified + } + console.log(file.name); + }); + } catch (err) { + console.error(`ls: cannot access '${directory}': No such file or directory`); + } +} + +function main() { + const args = process.argv.slice(2); + const options = { + all: false, + }; + + let directories = ['.']; + + args.forEach((arg) => { + if (arg === '-1') { + // -1 is the default behavior, so no action needed + } else if (arg === '-a') { + options.all = true; + } else { + directories = [arg]; + } + }); + + directories.forEach((directory) => { + listFiles(directory, options); + }); +} + +main(); \ No newline at end of file From daac5ecd310b8071a20a65a51ade077651e945fb Mon Sep 17 00:00:00 2001 From: enjoy15 Date: Sat, 21 Mar 2026 13:19:53 +0000 Subject: [PATCH 3/3] complete wc exercise --- implement-shell-tools/wc/wc.js | 61 ++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 implement-shell-tools/wc/wc.js diff --git a/implement-shell-tools/wc/wc.js b/implement-shell-tools/wc/wc.js new file mode 100644 index 000000000..60171cf31 --- /dev/null +++ b/implement-shell-tools/wc/wc.js @@ -0,0 +1,61 @@ +#!/usr/bin/env node + +const fs = require('fs'); +const path = require('path'); + +function countFile(filePath, options) { + try { + const data = fs.readFileSync(filePath, 'utf8'); + + const lines = data.split('\n').length; + const words = data.split(/\s+/).filter(Boolean).length; + const bytes = Buffer.byteLength(data, 'utf8'); + + if (options.lines) { + console.log(`${lines}\t${filePath}`); + } else if (options.words) { + console.log(`${words}\t${filePath}`); + } else if (options.bytes) { + console.log(`${bytes}\t${filePath}`); + } else { + console.log(`${lines}\t${words}\t${bytes}\t${filePath}`); + } + } catch (err) { + console.error(`wc: ${filePath}: No such file or directory`); + } +} + +function main() { + const args = process.argv.slice(2); + const options = { + lines: false, + words: false, + bytes: false, + }; + + const files = []; + + args.forEach((arg) => { + if (arg === '-l') { + options.lines = true; + } else if (arg === '-w') { + options.words = true; + } else if (arg === '-c') { + options.bytes = true; + } else { + files.push(arg); + } + }); + + if (files.length === 0) { + console.error('Usage: wc [-l | -w | -c] ...'); + process.exit(1); + } + + files.forEach((file) => { + const filePath = path.resolve(file); + countFile(filePath, options); + }); +} + +main(); \ No newline at end of file