diff --git a/.gitignore b/.gitignore index 3c3629e64..47cb86610 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ node_modules +demo* +.* diff --git a/implement-shell-tools/cat/cat.py b/implement-shell-tools/cat/cat.py new file mode 100755 index 000000000..7e9a1febd --- /dev/null +++ b/implement-shell-tools/cat/cat.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python3 + +import argparse +import sys + +parser = argparse.ArgumentParser( + prog='cat', + description='CLI tool to concatenate and print files', +) + +parser.add_argument('-n', '--number', action='store_true', help='Number all outputs, starting at 1') +parser.add_argument('-b', '--nonBlank', action='store_true', help='Number only non-blank lines, starting at 1') +parser.add_argument('files', nargs='*', help='Files to read') + +args = parser.parse_args() +# print(args.number, args.nonBlank, args.files) +# print(sys.argv[0], sys.argv[1]) + + +for file in args.files: + count = 1 + try: + with open(file, 'r') as f: + for line in f: + if args.nonBlank: + if line.strip(): + print(f"{str(count).rjust(6)}\t{line}", end='') + count += 1 + else: + print(line, end="") + elif args.number: + print(f"{str(count).rjust(6)}\t{line}", end='') + count +=1 + else: + print(f"{line}", end="") + + except FileNotFoundError: + print(f"cat: {file}: No such file or directory.", file=sys.stderr) \ 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..4c9475577 --- /dev/null +++ b/implement-shell-tools/ls/ls.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python3 + +import argparse +import os +import sys + +parser = argparse.ArgumentParser( + prog='ls', + description='CLI tool to list contents of a directory' +) + +parser.add_argument('-1', '--one', action='store_true', help='Force output to be entry per line') +parser.add_argument('-a','--all', action='store_true', help='Include hidden files') +parser.add_argument('path', nargs='?', default='.', help='Directories to list') + +args = parser.parse_args() + +try: + entries = os.listdir(args.path) + # print(entries) + if not args.all: + entries = [entry for entry in entries if not entry.startswith('.')] + entries.sort(key=str.lower) + # print(entries) + + if args.one: + for entry in entries: + print(entry) + + else: + print(f" ".join(entries)) + +except FileNotFoundError: + print(f"ls: {args.path}: No such file or directory.", file=sys.stderr) \ 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..289b78cf4 --- /dev/null +++ b/implement-shell-tools/wc/wc.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python3 + +import argparse +import sys +import os + +parser = argparse.ArgumentParser( + prog='wc', + description='Displays number of words, lines, and bytes in a file' +) + +parser.add_argument('-l', '--lines', action='store_true', help='counts number of lines') +parser.add_argument('-w', '--words', action='store_true', help='counts sequence of characters') +parser.add_argument('-c', '--bytes', action='store_true', help='counts raw size of a file in bytes') +parser.add_argument('files', nargs='+', help='Files to read') + +args = parser.parse_args() + +if not args.files: + print(f"wc: missing file to read") + sys.exit(1) + +total_lines, total_words, total_bytes = 0, 0, 0 + +for file in args.files: + try: + with open(file, 'r') as f: + content = f.read() + + line_count = content.count('\n') + word_count = len(content.split()) + byte_count = os.path.getsize(file) + + total_lines += line_count + total_words += word_count + total_bytes += byte_count + + show_all = not (args.lines or args.words or args.bytes) + + output = "" + if args.lines or show_all: + output += f"{line_count:>7} " + if args.words or show_all: + output += f"{word_count:>7} " + if args.bytes or show_all: + output += f"{byte_count:>7} " + + print(f"{output} {file}") + + except FileNotFoundError: + print(f"wc: {args.path}: No such file or directory.", file=sys.stderr) + + +if len(args.files) > 1: + total = "" + if args.lines or show_all: + total += f"{total_lines:>7} " + if args.words or show_all: + total += f"{total_words:>7} " + if args.bytes or show_all: + total += f"{total_bytes:>7} " + + print(f"{total}total") \ No newline at end of file