diff --git a/implement-shell-tools/cat/cat.py b/implement-shell-tools/cat/cat.py new file mode 100644 index 00000000..b6aaa900 --- /dev/null +++ b/implement-shell-tools/cat/cat.py @@ -0,0 +1,36 @@ +import argparse + +parser = argparse.ArgumentParser( + prog="cat", + description="read, display, and concatenate text 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 to search") + +args = parser.parse_args() + +for path in args.paths: + try: + with open(path, mode='r', encoding='utf-8') as f: + lines = f.readlines() + + except Exception as err: + print(f"Error reading file '{path}': {err}") + continue + + line_num = 1 + + for line in lines: + if args.b: + if line.strip() != "": + print(f"{line_num:5} {line}", end="") + line_num += 1 + else: + print() + elif args.n: + print(f"{line_num:5} {line}", end="") + line_num += 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 00000000..0444284b --- /dev/null +++ b/implement-shell-tools/ls/ls.py @@ -0,0 +1,36 @@ +import argparse +import os +import sys + +parser = argparse.ArgumentParser( + prog="ls", + description="List all the files in a directory" +) + + +parser.add_argument("-a", "--all",action="store_true", help="Include hidden files") +parser.add_argument("-1", "--one", action="store_true",help="One entry per line") +parser.add_argument("dir", nargs="?" ,default=".", help="directory to list") + + +args = parser.parse_args() + + +try: + # Gets all file names (including hidden ones) + files = os.listdir(args.dir) +except (FileNotFoundError, NotADirectoryError) as err: + print(f"ls: can't access: '{args.dir}': {err}") + sys.exit(1) + +visible_names = [ + entry for entry in files + if args.all or not entry.startswith(".") +] + +visible_names.sort() + +if args.one: + print("\n".join(visible_names)) +else: + print("\t".join(visible_names)) \ 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 00000000..73e9bb8a --- /dev/null +++ b/implement-shell-tools/wc/wc.py @@ -0,0 +1,59 @@ +import argparse +import os + +parser = argparse.ArgumentParser( + prog="wc", + description="Display numbers of line, words, and bytes in each file" +) + +parser.add_argument("-l", action="store_true", help="Number of lines") +parser.add_argument("-w", action="store_true" ,help="Number of words") +parser.add_argument("-c", action="store_true" ,help="Number of bytes") +parser.add_argument("paths", nargs="+", help="The file to search") + +args = parser.parse_args() + +totalLines = 0 +totalWords = 0 +totalBytes = 0 + +lines = args.l +words = args.w +bytes = args.c + +for path in args.paths: + try: + with open(path, "r") as f: + content = f.read() + + except Exception as err: + print(f"Error reading file '{path}': {err}") + continue + + lineCount = len(content.split("/n")) + wordCount = len(content.split()) + byteCount = os.path.getsize(path) + + totalLines += lineCount + totalWords += wordCount + totalBytes += byteCount + + if lines: + print(f"\t{lineCount} {path}") + lineCount += 1 + elif words: + print(f"\t{wordCount} {path}") + elif bytes: + print(f"\t{byteCount} {path}") + else: + print(f"\t{lineCount} \t{wordCount} \t{byteCount} {path}") + +if len(args.paths) > 1: + if lines: + print(f"{totalLines} total") + elif words: + print(f"{totalWords} total") + elif bytes: + print(f"{totalBytes} total") + else: + print(f"\t{totalLines} \t{totalWords} \t{totalBytes} total") \ No newline at end of file