diff --git a/implement-shell-tools/cat/cat.py b/implement-shell-tools/cat/cat.py new file mode 100644 index 000000000..7dee05867 --- /dev/null +++ b/implement-shell-tools/cat/cat.py @@ -0,0 +1,33 @@ +import sys + +args = sys.argv[1:] + +number_all = "-n" in args +number_nonblank = "-b" in args + +files = [arg for arg in args if arg not in ("-n", "-b")] + +line_number = 1 + +for filename in files: + try: + with open(filename, "r") as file: + content = file.read() + + lines = content[:-1].split("\n") if content.endswith("\n") else content.split("\n") + + for line in lines: + if number_all: + print(f"{line_number:6}\t{line}") + line_number += 1 + + elif number_nonblank and line != "": + print(f"{line_number:6}\t{line}") + line_number += 1 + + else: + print(line) + + except Exception as err: + print(f"cat: {filename}: {err}") + \ No newline at end of file diff --git a/implement-shell-tools/ls/ls.py b/implement-shell-tools/ls/ls.py new file mode 100644 index 000000000..100673d4f --- /dev/null +++ b/implement-shell-tools/ls/ls.py @@ -0,0 +1,48 @@ +import sys +import os + +args = sys.argv[1:] + +one_line = False +show_hidden = False +targets = [] + +for arg in args: + if arg == "-1": + one_line = True + elif arg == "-a": + show_hidden = True + else: + targets.append(arg) + +if len(targets) == 0: + targets.append(".") + + +def list_directory(directory): + files = os.listdir(directory) + + if not show_hidden: + files = [file for file in files if not file.startswith(".")] + + files.sort() + + if one_line: + print("\n".join(files)) + else: + print(" ".join(files)) + + +def list_target(target): + try: + if os.path.isdir(target): + list_directory(target) + else: + print(target) + + except Exception: + print(f"ls: cannot access '{target}': No such file or directory") + + +for target in targets: + list_target(target) \ No newline at end of file diff --git a/implement-shell-tools/wc/wc.py b/implement-shell-tools/wc/wc.py new file mode 100644 index 000000000..384707252 --- /dev/null +++ b/implement-shell-tools/wc/wc.py @@ -0,0 +1,84 @@ +import sys + +args = sys.argv[1:] + +count_lines = False +count_words = False +count_bytes = False +files = [] + +for arg in args: + if arg == "-l": + count_lines = True + elif arg == "-w": + count_words = True + elif arg == "-c": + count_bytes = True + else: + files.append(arg) + +# If no flags are given, wc shows all three +if not count_lines and not count_words and not count_bytes: + count_lines = True + count_words = True + count_bytes = True + +def print_output(lines, words, bytes_count, label): + output = [] + + if count_lines: + output.append(f"{lines:8}") + + if count_words: + output.append(f"{words:8}") + + if count_bytes: + output.append(f"{bytes_count:8}") + + output.append(f" {label}") + + print("".join(output)) + + +def count_file(filename): + try: + with open(filename, "r") as file: + content = file.read() + + lines = content.count("\n") + + words = 0 if content.strip() == "" else len(content.split()) + + # UTF-8 bytes, same idea as Buffer.byteLength() + bytes_count = len(content.encode("utf-8")) + + print_output(lines, words, bytes_count, filename) + + return { + "lines": lines, + "words": words, + "bytes": bytes_count + } + + except Exception as err: + print(f"wc: {filename}: {err}") + return None + + +total_lines = 0 +total_words = 0 +total_bytes = 0 + + + +for file in files: + counts = count_file(file) + + if counts: + total_lines += counts["lines"] + total_words += counts["words"] + total_bytes += counts["bytes"] + + +if len(files) > 1: + print_output(total_lines, total_words, total_bytes, "total") \ No newline at end of file