From 7070feb621abcd5b745bcc72ac6ba96bbfb18fb0 Mon Sep 17 00:00:00 2001 From: RomanSanaye Date: Thu, 30 Jul 2026 16:18:36 +0100 Subject: [PATCH 1/6] Implemented cat with python --- implement-shell-tools/cat/cat.py | 57 ++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 implement-shell-tools/cat/cat.py diff --git a/implement-shell-tools/cat/cat.py b/implement-shell-tools/cat/cat.py new file mode 100644 index 000000000..7bebc2da4 --- /dev/null +++ b/implement-shell-tools/cat/cat.py @@ -0,0 +1,57 @@ +# in built module +import sys + +args = sys.argv[1:] + +flag = "" +file_paths = [] + + +# Check if the first argument is a flag like -n or -b +if args and args[0].startswith("-"): + flag = args[0] + file_paths = args[1:] +else: + file_paths = args + + +# Read all files and combine their contents into one string +content = "" + +for file in file_paths: + with open(file, "r") as f: + content += f.read() + + +# Split the file content into separate lines +lines = content.splitlines() + + +# Handle -n flag: add a number to every line +if flag == "-n": + new_lines = [] + + for index, line in enumerate(lines): + new_lines.append(f"{index + 1} {line}") + + lines = new_lines + + +# Handle -b flag: number only non-empty lines +if flag == "-b": + line_number = 1 + new_lines = [] + + for line in lines: + # Keep empty lines without adding numbers + if line.strip() == "": + new_lines.append(line) + + # Add a number only to lines that contain text + else: + new_lines.append(f"{line_number} {line}") + line_number += 1 + + lines = new_lines + +sys.stdout.write("\n".join(lines)) From b5eff5fa14210108618082b3186f5062e9c425c9 Mon Sep 17 00:00:00 2001 From: RomanSanaye Date: Thu, 30 Jul 2026 19:08:38 +0100 Subject: [PATCH 2/6] Implemented ls with python --- implement-shell-tools/ls/ls.py | 48 ++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 implement-shell-tools/ls/ls.py diff --git a/implement-shell-tools/ls/ls.py b/implement-shell-tools/ls/ls.py new file mode 100644 index 000000000..28293471b --- /dev/null +++ b/implement-shell-tools/ls/ls.py @@ -0,0 +1,48 @@ +# Access command-line arguments from the terminal +import sys + +# Work with the operating system (files and directories) +import os + +# Get command-line arguments +args = sys.argv[1:] + +flags = [] +paths = [] + + +# Separate flags and paths +for arg in args: + if arg.startswith("-"): + flags.append(arg) + else: + paths.append(arg) + + +# Use the current directory if no path is provided +if not paths: + paths = ["."] + + +# Process each path +for path in paths: + + # If the path is a file, print its name + if os.path.isfile(path): + print(path) + + # If the path is a directory, get its contents + elif os.path.isdir(path): + contents = os.listdir(path) + if "-a" not in flags: + contents=[ + file for file in contents + if not file.startswith(".") + ] + if "-1" in flags: + print("\n".join(contents)) + else: + print(" ".join(contents)) + # Handle invalid paths + else: + print(f"No such file or directory: {path}") From a73b96a0498f8a2594223c67803473dcb713390f Mon Sep 17 00:00:00 2001 From: RomanSanaye Date: Fri, 31 Jul 2026 00:26:04 +0100 Subject: [PATCH 3/6] Implemented wc in python version --- implement-shell-tools/wc/wc.py | 74 ++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 implement-shell-tools/wc/wc.py diff --git a/implement-shell-tools/wc/wc.py b/implement-shell-tools/wc/wc.py new file mode 100644 index 000000000..0822cbdf6 --- /dev/null +++ b/implement-shell-tools/wc/wc.py @@ -0,0 +1,74 @@ +import sys + +args = sys.argv[1:] + +flags = [] +paths = [] + +# Separate flags and paths +for arg in args: + if arg.startswith("-"): + flags.append(arg) + else: + paths.append(arg) + + +total_lines = 0 +total_words = 0 +total_chars = 0 + + +for file in paths: + + # Read file as bytes + with open(file, "rb") as f: + content = f.read() + + # Count + lines = content.count(b"\n") + words = len(content.split()) + chars = len(content) + + # Output for this file + output = [] + + if len(flags) == 0: + output = [lines, words, chars] + + else: + if "-l" in flags: + output.append(lines) + + if "-w" in flags: + output.append(words) + + if "-c" in flags: + output.append(chars) + + print(*output, file) + + # Add to totals + total_lines += lines + total_words += words + total_chars += chars + + +# Print total only when multiple files +if len(paths) > 1: + + total_output = [] + + if len(flags) == 0: + total_output = [total_lines, total_words, total_chars] + + else: + if "-l" in flags: + total_output.append(total_lines) + + if "-w" in flags: + total_output.append(total_words) + + if "-c" in flags: + total_output.append(total_chars) + + print(*total_output, "total") From f68a6755ffa684c9f14cedce5108dc816da1dc89 Mon Sep 17 00:00:00 2001 From: RomanSanaye Date: Tue, 4 Aug 2026 22:44:12 +0100 Subject: [PATCH 4/6] Use argparse for cat argument parsing --- implement-shell-tools/cat/cat.py | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/implement-shell-tools/cat/cat.py b/implement-shell-tools/cat/cat.py index 7bebc2da4..4747649dc 100644 --- a/implement-shell-tools/cat/cat.py +++ b/implement-shell-tools/cat/cat.py @@ -1,18 +1,22 @@ # in built module -import sys +import argparse -args = sys.argv[1:] +parser = argparse.ArgumentParser() + +parser.add_argument("-n", action="store_true") +parser.add_argument("-b", action="store_true") +parser.add_argument("file_paths", nargs="+") + +args = parser.parse_args() flag = "" -file_paths = [] +if args.n: + flag = "-n" +elif args.b: + flag = "-b" -# Check if the first argument is a flag like -n or -b -if args and args[0].startswith("-"): - flag = args[0] - file_paths = args[1:] -else: - file_paths = args +file_paths = args.file_paths # Read all files and combine their contents into one string @@ -54,4 +58,4 @@ lines = new_lines -sys.stdout.write("\n".join(lines)) +print("\n".join(lines)) From 6ef3bd57d49bf8fc4066d0346dc449f5cca72b7b Mon Sep 17 00:00:00 2001 From: RomanSanaye Date: Tue, 4 Aug 2026 23:02:14 +0100 Subject: [PATCH 5/6] Use argparse for ls argument parsing --- implement-shell-tools/ls/ls.py | 35 +++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/implement-shell-tools/ls/ls.py b/implement-shell-tools/ls/ls.py index 28293471b..ecfe3290e 100644 --- a/implement-shell-tools/ls/ls.py +++ b/implement-shell-tools/ls/ls.py @@ -1,22 +1,26 @@ -# Access command-line arguments from the terminal -import sys - -# Work with the operating system (files and directories) +import argparse import os -# Get command-line arguments -args = sys.argv[1:] +# Set up command-line argument parser +parser = argparse.ArgumentParser() + +# Add supported flags and file/directory paths +parser.add_argument("-a", action="store_true") +parser.add_argument("-1", dest="one", action="store_true") +parser.add_argument("paths", nargs="*") + +# Parse the user's command-line arguments +args = parser.parse_args() flags = [] -paths = [] +if args.a: + flags.append("-a") -# Separate flags and paths -for arg in args: - if arg.startswith("-"): - flags.append(arg) - else: - paths.append(arg) +if args.one: + flags.append("-1") + +paths = args.paths # Use the current directory if no path is provided @@ -35,10 +39,7 @@ elif os.path.isdir(path): contents = os.listdir(path) if "-a" not in flags: - contents=[ - file for file in contents - if not file.startswith(".") - ] + contents = [file for file in contents if not file.startswith(".")] if "-1" in flags: print("\n".join(contents)) else: From 860d37bf936c90f7147ada82b76ccd185214c5b7 Mon Sep 17 00:00:00 2001 From: RomanSanaye Date: Tue, 4 Aug 2026 23:57:54 +0100 Subject: [PATCH 6/6] Use argparse and improve wc output formatting --- implement-shell-tools/wc/wc.py | 93 +++++++++++++++++++--------------- 1 file changed, 53 insertions(+), 40 deletions(-) diff --git a/implement-shell-tools/wc/wc.py b/implement-shell-tools/wc/wc.py index 0822cbdf6..622299ae6 100644 --- a/implement-shell-tools/wc/wc.py +++ b/implement-shell-tools/wc/wc.py @@ -1,37 +1,39 @@ -import sys +import argparse -args = sys.argv[1:] +# Set up command-line argument parser +parser = argparse.ArgumentParser() -flags = [] -paths = [] +# Add supported flags +parser.add_argument("-l", action="store_true") +parser.add_argument("-w", action="store_true") +parser.add_argument("-c", action="store_true") -# Separate flags and paths -for arg in args: - if arg.startswith("-"): - flags.append(arg) - else: - paths.append(arg) +# Accept one or more file paths +parser.add_argument("paths", nargs="+") +# Parse the user's command-line arguments +args = parser.parse_args() -total_lines = 0 -total_words = 0 -total_chars = 0 +flags = [] +# Store selected flags for the existing logic +if args.l: + flags.append("-l") -for file in paths: +if args.w: + flags.append("-w") - # Read file as bytes - with open(file, "rb") as f: - content = f.read() +if args.c: + flags.append("-c") - # Count - lines = content.count(b"\n") - words = len(content.split()) - chars = len(content) +paths = args.paths - # Output for this file + +# Build the output based on the selected flags +def get_output(lines, words, chars, flags): output = [] + # Show all counts when no flag is provided if len(flags) == 0: output = [lines, words, chars] @@ -45,30 +47,41 @@ if "-c" in flags: output.append(chars) - print(*output, file) + return output - # Add to totals - total_lines += lines - total_words += words - total_chars += chars + +total_lines = 0 +total_words = 0 +total_chars = 0 -# Print total only when multiple files -if len(paths) > 1: +# Process each file +for file in paths: - total_output = [] + # Read file as bytes + with open(file, "rb") as f: + content = f.read() - if len(flags) == 0: - total_output = [total_lines, total_words, total_chars] + # Count lines, words, and characters + lines = content.count(b"\n") + words = len(content.split()) + chars = len(content) - else: - if "-l" in flags: - total_output.append(total_lines) + # Create and print output for this file + output = get_output(lines, words, chars, flags) - if "-w" in flags: - total_output.append(total_words) + # Print counts with aligned columns + print(" ".join(f"{value:3}" for value in output), file) - if "-c" in flags: - total_output.append(total_chars) + # Add this file's counts to the totals + total_lines += lines + total_words += words + total_chars += chars + + +# Print total only when multiple files are provided +if len(paths) > 1: + total_output = get_output(total_lines, total_words, total_chars, flags) - print(*total_output, "total") + # Print aligned total + print(" ".join(f"{value:3}" for value in total_output), "total")