Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions implement-shell-tools/cat/cat.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { program } from "commander";
import { promises as fs } from "node:fs";

program
.name("my-cat")
.description("Reimplementation of the Unix `cat` command with -n and -b support")
.option("-n", "number all lines")
.option("-b", "number non-empty lines")
.argument("<files...>", "files to read");

program.parse();

const options = program.opts();
const filePaths = program.args;

let lineNumber = 1;

for (const filePath of filePaths) {
const content = await fs.readFile(filePath, "utf-8");

for (const line of content.split("\n")) {
if (options.n) {
console.log(`${String(lineNumber).padStart(6, ' ')} ${line}`);
lineNumber++;
} else if (options.b) {
if (line.trim()) {
console.log(`${String(lineNumber).padStart(6, ' ')} ${line}`);
lineNumber++;
} else {
console.log("");
}
} else {
console.log(line);
}
}
}
28 changes: 28 additions & 0 deletions implement-shell-tools/ls/ls.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { program } from "commander";
import { promises as fs } from "node:fs";

program
.name("my-ls")
.description("Reimplementation of the Unix `ls` command with -1 and -a options")
.option("-1", "list one file per line")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You have an option allowing one line per file. What does the user do if they dont want one line per file?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the feedback! You're right. I updated the code so that if -1 is not passed, the files will now be shown in a single line, just like the default ls command.

.option("-a", "include hidden files")
.argument("[directory]", "directory to list");

program.parse();

const options = program.opts();

const directory = program.args[0] || "."; // Use current directory as default if no argument is provided

const files = await fs.readdir(directory);

const visibleFiles = options.a ? files : files.filter(file => !file.startsWith("."));

if (options["1"]) {
for (const file of visibleFiles) {
console.log(file);
}
} else {
console.log(visibleFiles.join(" "));
}

25 changes: 25 additions & 0 deletions implement-shell-tools/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions implement-shell-tools/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "implement-shell-tools",
"version": "1.0.0",
"description": "Your task is to re-implement shell tools you have used.",
"main": "index.js",
"type": "module",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"commander": "^14.0.0"
}
}
55 changes: 55 additions & 0 deletions implement-shell-tools/wc/wc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { program } from "commander";
import { promises as fs } from "node:fs";

program
.name("my-wc")
.description("Reimplementation of the Unix `wc` command supporting -l, -w, and -c flags")
.option("-l", "show line count")
.option("-w", "show word count")
.option("-c", "show character count")
.argument("<files...>", "files to read");

program.parse();

const options = program.opts();
const filePaths = program.args;

function formatCounts(lines, words, chars, options) {
let result = "";

if (options.l || options.w || options.c) {
if (options.l) result += `${lines} `;
if (options.w) result += `${words} `;
if (options.c) result += `${chars} `;
} else {
result += `${lines} ${words} ${chars} `;
}

return result;
}

let totalLines = 0;
let totalWords = 0;
let totalChars = 0;

for (const filePath of filePaths) {
const content = await fs.readFile(filePath, "utf-8");

const lineCount = (content.match(/\n/g) || []).length;
const wordCount = content.trim().split(/\s+/).length;
const charCount = content.length;

totalLines += lineCount;
totalWords += wordCount;
totalChars += charCount;

const output = formatCounts(lineCount, wordCount, charCount, options);

console.log(`${output}${filePath}`);
}

if (filePaths.length > 1) {
const totalOutput = formatCounts(totalLines, totalWords, totalChars, options);

console.log(`${totalOutput}total`);
}