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
47 changes: 47 additions & 0 deletions implement-shell-tools/cat/cat.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { program } from "commander";
import{promises as fs} from "node:fs";


program
.name("cat")
.description("displays the contents of a file")
.option("-n, --number", "Number all output lines")
.option("-b, --number-nonblank", "Number non-blank output lines only")
.argument("<filepaths...>");

program.parse();


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

if (args.length === 0) {
console.error("Error: Missing <filepath> argument.");
program.help();
}

let globalLineNumber = 1;

for (const path of args) {
try {
const content = await fs.readFile(path, "utf-8");
const lines = content.split('\n');

if (opts.number) {
lines.forEach((line, idx) => {
console.log(`${idx + 1}\t${line}`);
});
} else if (opts.numberNonblank) {
for (const line of lines) {
if (line.trim() !== '') {
console.log(`${globalLineNumber}\t${line}`);
globalLineNumber++;
}
}
} else {
console.log(content);
}
} catch (err) {
console.error(`Error reading file "${path}": ${err.message}`);
}
}
33 changes: 33 additions & 0 deletions implement-shell-tools/ls/ls.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import {program} from "commander";
import {promises as fs} from "node:fs";

program
.name("ls")
.description("displays files in a directory")
.option("-1, --one", "displays each file in its own line")
.option("-a, --all", "displays all files including hidden files")
.arguments("<filepath>")

await program.parseAsync();

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

if (args.length === 0) {
console.error("Error: Missing <filepath> argument.");
program.help();
}

const path = args[0];
const files = await fs.readdir(path);

let visibleFiles = files;
if (!opts.all) {
visibleFiles = files.filter(file => !file.startsWith("."));
}

if (opts.one) {
visibleFiles.forEach(console.log);
} else {
console.log(visibleFiles.join(" "));
}
72 changes: 72 additions & 0 deletions implement-shell-tools/wc/wc.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import {program} from "commander";
import{promises as fs} from "node:fs";

program
.name("wc")
.description("counts lines, words, and bytes")
.option("-l, --line", "counts number of lines in the file")
.option("-w, --words", "counts number of words in the file")
.option("-c, --bytes", "counts number of bytes in the file")
.argument("<filepaths...>")

program.parse();

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

if(args.length === 0){
console.error("Error: Missing <filepath> argument.");
program.help();
}

const countLines = content => content.split(/\r?\n/).length;
const countWords = content => content.trim().split(/\s+/).filter(Boolean).length;
const countBytes = content => Buffer.byteLength(content, "utf-8");

// store totals for multiple files
let totalLines = 0;
let totalWords = 0;
let totalBytes = 0;

for (const path of args) {
try {
const content = await fs.readFile(path, "utf-8");

const lines = countLines(content);
const words = countWords(content);
const bytes = countBytes(content);

totalLines += lines;
totalWords += words;
totalBytes += bytes;

// collect counts based on options
const output = [];
if (opts.line) output.push(lines);
if (opts.words) output.push(words);
if (opts.bytes) output.push(bytes);

// if no options are passed, print all
if (!opts.line && !opts.words && !opts.bytes) {
output.push(lines, words, bytes);
}

console.log(...output, path);
} catch (err) {
console.error(`Error reading file "${path}": ${err.message}`);
}
}

// print totals if more than one file
if (args.length > 1) {
const totalOutput = [];
if (opts.line) totalOutput.push(totalLines);
if (opts.words) totalOutput.push(totalWords);
if (opts.bytes) totalOutput.push(totalBytes);

if (!opts.line && !opts.words && !opts.bytes) {
totalOutput.push(totalLines, totalWords, totalBytes);
}

console.log(...totalOutput, "total");
}
1 change: 1 addition & 0 deletions individual-shell-tools/ls/script-01.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ fi

# TODO: Write a command to list the files and folders in this directory.
# The output should be a list of names including child-directory, script-01.sh, script-02.sh, and more.
ls
1 change: 1 addition & 0 deletions individual-shell-tools/ls/script-02.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ set -euo pipefail

# TODO: Write a command which lists all of the files in the directory named child-directory.
# The output should be a list of names: helper-1.txt, helper-2.txt, helper-3.txt.
ls chile
Loading