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

def main():
parser = argparse.ArgumentParser(description="cat with -n and -b options")
parser.add_argument("-n", action="store_true", help="Number all output lines")
parser.add_argument("-b", action="store_true", help="Number non-blank lines (overrides -n)")
parser.add_argument("files", nargs="+", help="Files to read (supports *.txt)")
args = parser.parse_args()

# -b overrides -n
number_all = args.n
number_nonblank = args.b
if number_all and number_nonblank:
number_all = False

# Expand wildcard patterns (e.g. *.txt)
file_list = []
for pattern in args.files:
matched_files = glob.glob(pattern)
if matched_files:
file_list.extend(matched_files)
else:
file_list.append(pattern)

# Print contents of each file
line_number = 1
for filename in file_list:
try:
with open(filename, "r") as f:
for line in f:
text = line.rstrip("\n")
if number_nonblank:
if text.strip(): # only number non-blank lines
print(f"{line_number:6}\t{text}")
line_number += 1
else:
print()
elif number_all:
print(f"{line_number:6}\t{text}")
line_number += 1
else:
print(text)
except FileNotFoundError:
print(f"cat: {filename}: No such file or directory")

if __name__ == "__main__":
main()
23 changes: 23 additions & 0 deletions implement-shell-tools/ls/ls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import argparse
import os

parser = argparse.ArgumentParser(description="Display one file per line from ls directory")

parser.add_argument("-1", dest="one", action="store_true", help="List one file per line")
parser.add_argument("-a", action="store_true", help="Include hidden files (those starting with .)")
parser.add_argument("path", nargs="?", default=".", help="The directory to list (default: current directory)")

args = parser.parse_args()


files = sorted(os.listdir(args.path))


if not args.a:
files = [f for f in files if not f.startswith(".")]

if args.one:
for f in files:
print(f)
else:
print(" ".join(files))
78 changes: 78 additions & 0 deletions implement-shell-tools/wc/wc.py

Choose a reason for hiding this comment

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

Good work implementing this, there is some duplication in your code though, can you spot this and improve it?

Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import argparse
import glob

def count_file(filename):
line_count = 0
word_count = 0
byte_count = 0

try:
with open(filename, "rb") as f:
content = f.read()
byte_count = len(content)
text = content.decode("utf-8", errors="replace")
lines = text.splitlines()
line_count = len(lines)
word_count = sum(len(line.split()) for line in lines)

return (line_count, word_count, byte_count)
except FileNotFoundError:
print(f"wc: {filename}: No such file or directory")
return None

def main():
parser = argparse.ArgumentParser(description="Python version of wc")
parser.add_argument("-l", action="store_true", help="Count lines")
parser.add_argument("-w", action="store_true", help="Count words")
parser.add_argument("-c", action="store_true", help="Count bytes")
parser.add_argument("files", nargs="+", help="Files to read (supports wildcards)")
args = parser.parse_args()

# If no flag is given, show all
show_lines = args.l
show_words = args.w
show_bytes = args.c
if not (show_lines or show_words or show_bytes):
show_lines = show_words = show_bytes = True

file_list = []
for pattern in args.files:
matched = glob.glob(pattern)
if matched:
file_list.extend(matched)
else:
file_list.append(pattern)

total_lines = total_words = total_bytes = 0
for filename in file_list:
result = count_file(filename)
if result is None:
continue
lines, words, bytes_ = result
total_lines += lines
total_words += words
total_bytes += bytes_

output = []
if show_lines:
output.append(f"{lines:7}")
if show_words:
output.append(f"{words:7}")
if show_bytes:
output.append(f"{bytes_:7}")
output.append(filename)
print(" ".join(output))

if len(file_list) > 1:
output = []
if show_lines:
output.append(f"{total_lines:7}")
if show_words:
output.append(f"{total_words:7}")
if show_bytes:
output.append(f"{total_bytes:7}")
output.append("total")
print(" ".join(output))

if __name__ == "__main__":
main()