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
61 changes: 61 additions & 0 deletions implement-shell-tools/cat/cat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# in built module
import argparse

parser = argparse.ArgumentParser()

parser.add_argument("-n", action="store_true")
parser.add_argument("-b", action="store_true")
parser.add_argument("file_paths", nargs="+")

args = parser.parse_args()

flag = ""

if args.n:
flag = "-n"
elif args.b:
flag = "-b"

file_paths = args.file_paths


# Read all files and combine their contents into one string
content = ""

for file in file_paths:
with open(file, "r") as f:
content += f.read()


# Split the file content into separate lines
lines = content.splitlines()


# Handle -n flag: add a number to every line
if flag == "-n":
new_lines = []

for index, line in enumerate(lines):
new_lines.append(f"{index + 1} {line}")

lines = new_lines


# Handle -b flag: number only non-empty lines
if flag == "-b":
line_number = 1
new_lines = []

for line in lines:
# Keep empty lines without adding numbers
if line.strip() == "":
new_lines.append(line)

# Add a number only to lines that contain text
else:
new_lines.append(f"{line_number} {line}")
line_number += 1

lines = new_lines

print("\n".join(lines))
49 changes: 49 additions & 0 deletions implement-shell-tools/ls/ls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import argparse
import os

# Set up command-line argument parser
parser = argparse.ArgumentParser()

# Add supported flags and file/directory paths
parser.add_argument("-a", action="store_true")
parser.add_argument("-1", dest="one", action="store_true")
parser.add_argument("paths", nargs="*")

# Parse the user's command-line arguments
args = parser.parse_args()

flags = []

if args.a:
flags.append("-a")

if args.one:
flags.append("-1")

paths = args.paths


# Use the current directory if no path is provided
if not paths:
paths = ["."]


# Process each path
for path in paths:

# If the path is a file, print its name
if os.path.isfile(path):
print(path)

# If the path is a directory, get its contents
elif os.path.isdir(path):
contents = os.listdir(path)
if "-a" not in flags:
contents = [file for file in contents if not file.startswith(".")]
if "-1" in flags:
print("\n".join(contents))
else:
print(" ".join(contents))
# Handle invalid paths
else:
print(f"No such file or directory: {path}")
87 changes: 87 additions & 0 deletions implement-shell-tools/wc/wc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import argparse

# Set up command-line argument parser
parser = argparse.ArgumentParser()

# Add supported flags
parser.add_argument("-l", action="store_true")
parser.add_argument("-w", action="store_true")
parser.add_argument("-c", action="store_true")

# Accept one or more file paths
parser.add_argument("paths", nargs="+")

# Parse the user's command-line arguments
args = parser.parse_args()

flags = []

# Store selected flags for the existing logic
if args.l:
flags.append("-l")

if args.w:
flags.append("-w")

if args.c:
flags.append("-c")

paths = args.paths


# Build the output based on the selected flags
def get_output(lines, words, chars, flags):
output = []

# Show all counts when no flag is provided
if len(flags) == 0:
output = [lines, words, chars]

else:
if "-l" in flags:
output.append(lines)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If you run this with multiple files, how does the output look? What change could make it neater?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Thanks. I’ve updated the output formatting to make the results neater when using multiple files.


if "-w" in flags:
output.append(words)

if "-c" in flags:
output.append(chars)

return output


total_lines = 0
total_words = 0
total_chars = 0


# Process each file
for file in paths:

# Read file as bytes
with open(file, "rb") as f:
content = f.read()

# Count lines, words, and characters
lines = content.count(b"\n")
words = len(content.split())
chars = len(content)

# Create and print output for this file
output = get_output(lines, words, chars, flags)

# Print counts with aligned columns
print(" ".join(f"{value:3}" for value in output), file)

# Add this file's counts to the totals
total_lines += lines
total_words += words
total_chars += chars


# Print total only when multiple files are provided
if len(paths) > 1:
total_output = get_output(total_lines, total_words, total_chars, flags)

# Print aligned total
print(" ".join(f"{value:3}" for value in total_output), "total")
Loading