diff --git a/.gitignore b/.gitignore index c4234ab74..91eecaeec 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,5 @@ node_modules testoutput.txt +.venv +__pycache__ +*.pyc \ No newline at end of file diff --git a/implement-shell-tools/cat/cat.py b/implement-shell-tools/cat/cat.py new file mode 100644 index 000000000..6abf8e9f7 --- /dev/null +++ b/implement-shell-tools/cat/cat.py @@ -0,0 +1,47 @@ +import argparse + +parser = argparse.ArgumentParser( + prog="cat", + description="Concatenate and print files", +) + +parser.add_argument( + "-n", + action="store_true", + help="Number all output lines" +) + +parser.add_argument( + "-b", + action="store_true", + help="Number non-blank output lines" +) + +parser.add_argument( + "paths", + nargs="+", + help="The file(s) to print", +) + +args = parser.parse_args() + +line_number = 1 + +for path in args.paths: + with open (path, "r") as f: + lines = f.readlines() + + for line in lines: + is_blank = line.strip() == "" + + if args.b: + if is_blank: + print(line, end="") + else: + print(f"{line_number:>6}\t{line}", end="") + line_number += 1 + elif args.n: + print(f"{line_number:>6}\t{line}", end="") + line_number += 1 + else: + print(line, end="") \ 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..4682880d0 --- /dev/null +++ b/implement-shell-tools/ls/ls.py @@ -0,0 +1,41 @@ +import argparse +import os + +parser = argparse.ArgumentParser( + prog="ls", + description="List directory content", +) + +parser.add_argument( + "-1", + action="store_true", + dest="one", + help="List one file per line", +) + +parser.add_argument( + "-a", + action="store_true", + help="Do not ignore entries starting with .", +) + +parser.add_argument( + "path", + nargs="?", + default=".", + help="The directory to list", +) + +args = parser.parse_args() + +items = os.listdir(args.path) + +if args.a: + items = [".", ".."] + items +else: + items = [item for item in items if not item.startswith(".")] + +items = sorted(items, key=lambda item: item.lstrip(".").lower()) + +for item in items: + print(item) \ 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..955ea9fc0 --- /dev/null +++ b/implement-shell-tools/wc/wc.py @@ -0,0 +1,77 @@ +import argparse + +parser = argparse.ArgumentParser( + prog="wc", + description="Count lines, words and characters in files", +) + +parser.add_argument( + "-l", + action="store_true", + help="Count lines only" +) + +parser.add_argument( + "-w", + action="store_true", + help="Count words only" +) + +parser.add_argument( + "-c", + action="store_true", + help="Count characters only", +) + +parser.add_argument( + "paths", + nargs="+", + help="The file(s) to count", +) + +args = parser.parse_args() + +total_lines = 0 +total_words = 0 +total_chars = 0 + +counts = [] + +for path in args.paths: + with open(path, "r") as f: + content = f.read() + + lines = len(content.splitlines()) + words = len(content.split()) + chars = len(content) + + total_lines += lines + total_words += words + total_chars += chars + + counts.append((lines, words, chars, path)) + +width_lines = max(len(str(total_lines)) + 1, 2) +width_words = max(len(str(total_words)) + 1, 3) +width_chars = max(len(str(total_chars)) + 1, 4) + +for lines, words, chars, path in counts: + if args.l: + print(f"{lines:>{width_lines}} {path}") + elif args.w: + print(f"{words:>{width_words}} {path}") + elif args.c: + print(f"{chars:>{width_chars}} {path}") + else: + print(f"{lines:>{width_lines}}{words:>{width_words}}{chars:>{width_chars}} {path}") + +if len(args.paths) > 1: + if args.l: + print(f"{total_lines:>{width_lines}} total") + elif args.w: + print(f"{total_words:>{width_words}} total") + elif args.c: + print(f"{total_chars:>{width_chars}} total") + else: + print(f"{total_lines:>{width_lines}}{total_words:>{width_words}}{total_chars:>{width_chars}} total") +