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/implement-shell-tools-python/cat/cat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#!/usr/bin/env python3
import sys
import os

global_line_counter = 1

def print_file(file_path, options):
global global_line_counter
try:
with open(file_path, "r", encoding="utf-8") as f:
content = f.read()

lines = content.split("\n")
if lines and lines[-1] == "":
lines.pop()

for line in lines:
prefix = ""

should_number = (
options["number_mode"] == "all" or
(options["number_mode"] == "non-empty" and line.strip() != "")
)

if should_number:
prefix = f"{global_line_counter:6}\t"
global_line_counter += 1

sys.stdout.write(prefix + line + "\n")

except Exception as e:
print(f"cat: {file_path}: {e}", file=sys.stderr)
sys.exit(1)


def main():
global global_line_counter
args = sys.argv[1:]

options = {"number_mode": "off"}
files = []

for arg in args:
if arg == "-n":
options["number_mode"] = "all"
elif arg == "-b":
options["number_mode"] = "non-empty"
else:
files.append(arg)

if not files:
print("cat: missing file operand", file=sys.stderr)
sys.exit(1)

for file_path in files:
global_line_counter = 1
print_file(file_path, options)


if __name__ == "__main__":
main()
47 changes: 47 additions & 0 deletions implement-shell-tools/implement-shell-tools-python/ls/ls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#!/usr/bin/env python3
import sys
import os

def list_directory(path, show_all, one_per_line):
try:
entries = os.listdir(path)
if show_all:
# Add . and .. when -a is used
entries = [".", ".."] + entries
else:
entries = [e for e in entries if not e.startswith(".")]

entries.sort(key=lambda x: (x not in (".", ".."), x))

for e in entries:
print(e)

except Exception as e:
print(f"Error reading directory {path}: {e}", file=sys.stderr)
sys.exit(1)


def main():
args = sys.argv[1:]

show_all = "-a" in args
one_per_line = "-1" in args

dirs = [a for a in args if a not in ("-a", "-1")]

if not dirs:
dirs = [os.getcwd()]

for i, path in enumerate(dirs):
if os.path.isdir(path):
if len(dirs) > 1:
print(f"{path}:")
list_directory(path, show_all, one_per_line)
if len(dirs) > 1 and i < len(dirs) - 1:
print("")
else:
print(path)


if __name__ == "__main__":
main()
70 changes: 70 additions & 0 deletions implement-shell-tools/implement-shell-tools-python/wc/wc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#!/usr/bin/env python3
import sys

def count_file_content(content):
raw_lines = content.split("\n")
lines = len(raw_lines) - 1 if raw_lines[-1] == "" else len(raw_lines)
words = len(content.split())
bytes_ = len(content.encode("utf-8"))
return lines, words, bytes_


def print_counts(path, counts, options):
parts = []
if options["line"]:
parts.append(str(counts[0]).rjust(8))
if options["word"]:
parts.append(str(counts[1]).rjust(8))
if options["byte"]:
parts.append(str(counts[2]).rjust(8))

output = "".join(parts)
print(f"{output} {path}")


def main():
args = sys.argv[1:]

options = {"line": False, "word": False, "byte": False}
files = []

for arg in args:
if arg == "-l":
options["line"] = True
elif arg == "-w":
options["word"] = True
elif arg == "-c":
options["byte"] = True
else:
files.append(arg)

if not files:
print("No files specified", file=sys.stderr)
sys.exit(1)

if not any(options.values()):
options = {"line": True, "word": True, "byte": True}

total = [0, 0, 0]
multiple = len(files) > 1

for path in files:
try:
with open(path, "r", encoding="utf-8") as f:
content = f.read()

counts = count_file_content(content)
total = [t + c for t, c in zip(total, counts)]

print_counts(path, counts, options)

except Exception as e:
print(f"Error reading file {path}: {e}", file=sys.stderr)
sys.exit(1)

if multiple:
print_counts("total", total, options)


if __name__ == "__main__":
main()
Loading