Skip to content
30 changes: 30 additions & 0 deletions implement-shell-tools/cat/cat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import argparse


parser = argparse.ArgumentParser(
prog="cat implemnet by Python"
)

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

args = parser.parse_args()

line_number = 1

for filename in args.files:

with open(filename) as file:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

What happens if filename doesn't exist? You might try with error handling for FileNotFoundError.

for line in file:
line = line.rstrip("\n")

if args.b and line == "":
print()
continue

if args.n or args.b:
print(f"{line_number} {line}")
line_number += 1
else:
print(line)
33 changes: 33 additions & 0 deletions implement-shell-tools/ls/ls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import argparse
import os

parser = argparse.ArgumentParser(
prog="ls implemnet by Python"
)

parser.add_argument("-1", action="store_true", dest="one_per_line")
parser.add_argument("-a", action="store_true", dest="show_all")
parser.add_argument("paths", nargs="*")

args = parser.parse_args()

if not args.paths:
args.paths = ["."]

for path in args.paths:
if os.path.isdir(path):
files = sorted(os.listdir(path))

if not args.show_all:
files = [file for file in files if not file.startswith(".")]

if args.one_per_line:
for file in files:
print(file)
else:
for file in files:
print(file, end=" ")
print()

else:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

what happens if we try like python ls.py completely_fake_file.txt?

Your current condition checks if it's a directory but what if it is a file. Shall we just print or do something with that condition?

And what if it's neither of dir nor file? How do we handle that?

print(path)
51 changes: 51 additions & 0 deletions implement-shell-tools/wc/wc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import argparse


parser = argparse.ArgumentParser()

parser.add_argument("-l", action="store_true")
parser.add_argument("-w", action="store_true")
parser.add_argument("-c", action="store_true")
parser.add_argument("files", nargs="+")

args = parser.parse_args()


def add_count(output, value):
output.append(str(value))


total_lines = 0
total_words = 0
total_bytes = 0

for filename in args.files:

with open(filename, "rb") as file:
content = file.read()

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Reading the whole file with .read() is putting that data into RAM. What if you point this at a 50GB log file? Check out this code for learning a better approach here


lines = content.count(b"\n")
words = len(content.split())
bytes_count = len(content)

total_lines += lines
total_words += words
total_bytes += bytes_count

if not args.l and not args.w and not args.c:
print(f"{lines:8} {words:8} {bytes_count:8} {filename}")

else:
output = []

if args.l:
add_count(output, lines)

if args.w:
add_count(output, words)

if args.c:
add_count(output, bytes_count)

print(f"{' '.join(output):>8} {filename}")

Loading