diff --git a/.gitignore b/.gitignore index 3c3629e6..3cceec8a 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ node_modules +/.venv +implement-cowsay/.venv/ diff --git a/implement-shell-tools/cat/cat.py b/implement-shell-tools/cat/cat.py new file mode 100644 index 00000000..019c5d81 --- /dev/null +++ b/implement-shell-tools/cat/cat.py @@ -0,0 +1,44 @@ +import argparse + +parser = argparse.ArgumentParser( + prog="cat", + usage="implement a simple cat" +) + +# Flag to number all lines +parser.add_argument( + "-n", + action="store_true", + help="Number all output lines" +) + +# Flag to number only non-blank lines +parser.add_argument( + "-b", + action="store_true", + help="Number non-blank output lines" +) + +# Positional argument for files to read +parser.add_argument( + "path", + nargs="*", + help="Files to read" +) + +args = parser.parse_args() +# print(args) +line_number=1 +for per_file in args.path : + with open(per_file,"r") as f: + if args.n or args.b : + lines=f.readlines() + for line in lines : + if line=="\n" and args.b : + print(line,end="") + else : + print(line_number,line,end="") + line_number=line_number+1 + else : + print(f.read(),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..b380cd6b --- /dev/null +++ b/implement-shell-tools/ls/ls.py @@ -0,0 +1,36 @@ +import os +import argparse + +parser=argparse.ArgumentParser(prog="cat",usage="implement a simple ls python") +parser.add_argument("-1",dest="one",action="store_true") +parser.add_argument("-a",action="store_true") +parser.add_argument("path",nargs="*",help="path to list files") +args=parser.parse_args() + +paths=args.path +if len(paths)==0 : paths=["."] + +for path in paths : + files_list=os.listdir(path) + files_list.sort(key=str.lower) + + # Divide into hidden and non-hidden + non_hidden = [f for f in files_list if not f.startswith(".")] + hidden = [f for f in files_list if f.startswith(".")] + + # Sort each list + non_hidden.sort(key=str.lower) + hidden.sort(key=str.lower) + + # Add '.' and '..' at the start if -a + if args.a: + files_list = ['.', '..'] + non_hidden + hidden + else: + files_list = non_hidden + +for item in files_list : + if args.one and args.a : + print(item) + elif args.one : + if not item.startswith(".") : + print(item) diff --git a/implement-shell-tools/wc/wc.py b/implement-shell-tools/wc/wc.py new file mode 100644 index 00000000..1fd7e660 --- /dev/null +++ b/implement-shell-tools/wc/wc.py @@ -0,0 +1,58 @@ +import argparse +import os + + +# Set up argument parser for wc command +parser=argparse.ArgumentParser(prog="wc",usage="implement a simple wc in python") +parser.add_argument("-l",action="store_true",help="count of lines") +parser.add_argument("-w",action="store_true",help="count of words") +parser.add_argument("-c",action="store_true",help="count of bytes") +parser.add_argument("path",nargs="+") +args=parser.parse_args() + + +paths=args.path +words_count=0 +total_lines=0 +total_words=0 +total_bytes=0 + +# Function to print counts for a file or total +def print_wc(lines, words, bytes_, name): + # Print selected counts in formatted columns + print( + (f"{lines:<5}" if args.l else "") + + (f"{words:<5}" if args.w else "") + + (f"{bytes_:<5}" if args.c else "") + + f"{name:<20}" + ) + +# Loop through all files +for file in paths : + with open(file,"r") as f : + # Get file size in bytes + bytes_count=os.path.getsize(file) + # Read all lines + lines=f.readlines() + lines_count=len(lines) + for line in lines : + # Count words in file + words_count+=len(line.split()) + + # Update totals + total_lines +=lines_count + total_bytes += bytes_count + total_words +=words_count + + # If no flags provided, default to showing all counts + if not (args.l or args.w or args.c): + args.l = True + args.w = True + args.c = True + # Print counts for this file + print_wc(lines_count, words_count, bytes_count, file) + +# If multiple files, print totals at the end +if len(paths)>1 : + print_wc(total_lines, total_words, total_bytes, "total") +