From f3b6b52cc920cbb2529b7dd915aa688724d5bb16 Mon Sep 17 00:00:00 2001 From: Nataliia Volkova Date: Sun, 30 Nov 2025 16:38:50 +0000 Subject: [PATCH 1/6] shell commands written by python --- implement-shell-tools/cat/cat.py | 42 +++++++++++++++++++++++ implement-shell-tools/ls/ls.py | 59 ++++++++++++++++++++++++++++++++ implement-shell-tools/wc/wc.py | 38 ++++++++++++++++++++ 3 files changed, 139 insertions(+) create mode 100644 implement-shell-tools/cat/cat.py create mode 100644 implement-shell-tools/ls/ls.py create mode 100644 implement-shell-tools/wc/wc.py diff --git a/implement-shell-tools/cat/cat.py b/implement-shell-tools/cat/cat.py new file mode 100644 index 00000000..8823729f --- /dev/null +++ b/implement-shell-tools/cat/cat.py @@ -0,0 +1,42 @@ +import argparse + +parser = argparse.ArgumentParser( + prog = "cat-command", + description = "cat shell command in python " +) + +parser.add_argument("-n", action="store_true", help="Display all lines numbers") +parser.add_argument("-b", action="store_true", help="Display numbers non-empty lines") +parser.add_argument("path", nargs="+", help="The file to search") + +args = parser.parse_args() + +for file_path in args.path: + with open(file_path, "r") as f: + content = f.readlines() + + if args.n: + number = 1 + for line in content: + print(f"{number}\t{line.strip()}") + number +=1 + elif args.b: + number = 1 + for line in content: + if line.strip() !="": + print(f"{number}\t{line.strip()}") + number +=1 + else: + print("") + else: + print("".join(content)) + + + + +# if args.b: +# number=1 +# for line in content: +# print + +# print(content) \ 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..5bab1d2f --- /dev/null +++ b/implement-shell-tools/ls/ls.py @@ -0,0 +1,59 @@ +import argparse +import os +import stat +import pwd +import grp +import time + +parser = argparse.ArgumentParser( + prog = "ls-command", + description= "ls shell command on python" +) + +parser.add_argument("-l", action="store_true", help="Display long format description files") +parser.add_argument("-a", action="store_true", help="Display hidden files along with visible") +parser.add_argument("path", nargs="*", default=["."], help="The file to search") + +args=parser.parse_args() + +def long_format(path, file): + info = os.stat(path) + permissions = stat.filemode(info.st_mode) + size_file = info.st_size + owner = pwd.getpwuid(info.st_uid).pw_name + group = grp.getgrgid(info.st_gid).gr_name + mtime = time.strftime("%b %d %H:%M", time.localtime(info.st_mtime)) + print (permissions, size_file, owner, group, mtime, file) + + + +for path in args.path: + if os.path.isfile(path): + file = os.path.basename(path) + if args.l: + long_format(path, file) + else: + print(file) + elif os.path.isdir(path): + files = os.listdir(path) + + if not args.a: + visible_files=[] + for file in files: + if not file.startswith("."): + visible_files.append(file) + files=visible_files + + for file in files: + full_file_path = os.path.join(path, file) + + if args.l: + long_format(full_file_path, file) + else: + print(file) + + + + + + diff --git a/implement-shell-tools/wc/wc.py b/implement-shell-tools/wc/wc.py new file mode 100644 index 00000000..d534aa6c --- /dev/null +++ b/implement-shell-tools/wc/wc.py @@ -0,0 +1,38 @@ +import argparse + +parser = argparse.ArgumentParser( + prog = "wc-count words, lines, characters", + description = "wc shell command on python" +) + +parser.add_argument("-l", action="store_true", help="Count lines") +parser.add_argument("-w", action="store_true", help="Count words") +parser.add_argument("-c", action="store_true", help="Counts bytes") +parser.add_argument("path", nargs="+", help="The file to search") + +args = parser.parse_args() + +for file_path in args.path: + with open(file_path, "r") as f: + content = f.readlines() + + text = "".join(content) + count_lines = len(content) + count_words = len(text.split()) + count_bytes=len(text.encode("utf-8")) + + if not (args.l or args.w or args.c): + print (count_lines, count_words, count_bytes, file_path) + if args.l: + print (count_lines, file_path) + if args.w: + print (count_words, file_path) + if args.c: + print (count_bytes, file_path) + + + + + + + From 87ed47e969fd9368c8e41f90f8e821410c406e53 Mon Sep 17 00:00:00 2001 From: Nataliia Volkova Date: Tue, 6 Jan 2026 19:10:43 +0000 Subject: [PATCH 2/6] correct numbering lines --- implement-shell-tools/cat/cat.py | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/implement-shell-tools/cat/cat.py b/implement-shell-tools/cat/cat.py index 8823729f..8733030d 100644 --- a/implement-shell-tools/cat/cat.py +++ b/implement-shell-tools/cat/cat.py @@ -10,18 +10,17 @@ parser.add_argument("path", nargs="+", help="The file to search") args = parser.parse_args() +number = 1 for file_path in args.path: with open(file_path, "r") as f: content = f.readlines() if args.n: - number = 1 for line in content: print(f"{number}\t{line.strip()}") number +=1 elif args.b: - number = 1 for line in content: if line.strip() !="": print(f"{number}\t{line.strip()}") @@ -29,14 +28,4 @@ else: print("") else: - print("".join(content)) - - - - -# if args.b: -# number=1 -# for line in content: -# print - -# print(content) \ No newline at end of file + print("".join(content)) \ No newline at end of file From e3aafe01a91a4eaba981238c570d2826c7d2479a Mon Sep 17 00:00:00 2001 From: Nataliia Volkova Date: Tue, 6 Jan 2026 20:27:47 +0000 Subject: [PATCH 3/6] Changes in wc.py according to the Readme requirements --- implement-shell-tools/wc/wc.py | 49 +++++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 12 deletions(-) diff --git a/implement-shell-tools/wc/wc.py b/implement-shell-tools/wc/wc.py index d534aa6c..00989132 100644 --- a/implement-shell-tools/wc/wc.py +++ b/implement-shell-tools/wc/wc.py @@ -12,23 +12,48 @@ args = parser.parse_args() + +count_total_lines = 0 +count_total_words = 0 +count_total_bytes = 0 + for file_path in args.path: - with open(file_path, "r") as f: - content = f.readlines() + with open(file_path, "r") as file: + content = file.read() - text = "".join(content) - count_lines = len(content) - count_words = len(text.split()) - count_bytes=len(text.encode("utf-8")) + count_lines = content.count("\n") + count_words = len(content.split()) + count_bytes=len(content.encode("utf-8")) + + count_total_lines += count_lines + count_total_words += count_words + count_total_bytes += count_bytes if not (args.l or args.w or args.c): print (count_lines, count_words, count_bytes, file_path) - if args.l: - print (count_lines, file_path) - if args.w: - print (count_words, file_path) - if args.c: - print (count_bytes, file_path) + else: + line = "" + if args.l: + line += f"{count_lines} " + if args.w: + line += f"{count_words} " + if args.c: + line += f"{count_bytes} " + line += f"{file_path}" + print(line) +if len(args.path) > 1: + if not (args.l or args.w or args.c): + print (count_total_lines, count_total_words, count_total_bytes, " total") + else: + line = "" + if args.l: + line += f"{count_total_lines} " + if args.w: + line += f"{count_total_words} " + if args.c: + line += f"{count_total_bytes} " + line += " total" + print(line) From 00276361fafcd130a3676281f0788d4015045077 Mon Sep 17 00:00:00 2001 From: Nataliia Volkova Date: Tue, 6 Jan 2026 21:41:07 +0000 Subject: [PATCH 4/6] added -1 flag, used ruff format command --- implement-shell-tools/ls/ls.py | 48 ++++++++++++++++------------------ 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/implement-shell-tools/ls/ls.py b/implement-shell-tools/ls/ls.py index 5bab1d2f..5813ef95 100644 --- a/implement-shell-tools/ls/ls.py +++ b/implement-shell-tools/ls/ls.py @@ -6,15 +6,21 @@ import time parser = argparse.ArgumentParser( - prog = "ls-command", - description= "ls shell command on python" + prog="ls-command", description="ls shell command on python" ) -parser.add_argument("-l", action="store_true", help="Display long format description files") -parser.add_argument("-a", action="store_true", help="Display hidden files along with visible") +parser.add_argument("-1", action="store_true", dest="one", help="One file per line") +parser.add_argument( + "-l", action="store_true", help="Display long format description files" +) +parser.add_argument( + "-a", action="store_true", help="Display hidden files along with visible" +) parser.add_argument("path", nargs="*", default=["."], help="The file to search") -args=parser.parse_args() + +args = parser.parse_args() + def long_format(path, file): info = os.stat(path) @@ -23,8 +29,7 @@ def long_format(path, file): owner = pwd.getpwuid(info.st_uid).pw_name group = grp.getgrgid(info.st_gid).gr_name mtime = time.strftime("%b %d %H:%M", time.localtime(info.st_mtime)) - print (permissions, size_file, owner, group, mtime, file) - + print(permissions, size_file, owner, group, mtime, file) for path in args.path: @@ -37,23 +42,16 @@ def long_format(path, file): elif os.path.isdir(path): files = os.listdir(path) - if not args.a: - visible_files=[] - for file in files: - if not file.startswith("."): - visible_files.append(file) - files=visible_files - - for file in files: - full_file_path = os.path.join(path, file) - - if args.l: - long_format(full_file_path, file) - else: - print(file) - - - - + if not args.a: + files = [file for file in files if not file.startswith(".")] + for file in files: + full_file_path = os.path.join(path, file) + if args.l: + long_format(full_file_path, file) + else: + if args.one: + print(file) + else: + print(file, "\n") From 558abe62ecce37c0f36d336aabcbc8e595b96921 Mon Sep 17 00:00:00 2001 From: Nataliia Volkova Date: Tue, 6 Jan 2026 21:45:17 +0000 Subject: [PATCH 5/6] com ruff format for rest files --- implement-shell-tools/cat/cat.py | 17 ++++++++--------- implement-shell-tools/wc/wc.py | 30 +++++++++++------------------- 2 files changed, 19 insertions(+), 28 deletions(-) diff --git a/implement-shell-tools/cat/cat.py b/implement-shell-tools/cat/cat.py index 8733030d..45438f42 100644 --- a/implement-shell-tools/cat/cat.py +++ b/implement-shell-tools/cat/cat.py @@ -1,12 +1,11 @@ import argparse parser = argparse.ArgumentParser( - prog = "cat-command", - description = "cat shell command in python " + prog="cat-command", description="cat shell command in python " ) -parser.add_argument("-n", action="store_true", help="Display all lines numbers") -parser.add_argument("-b", action="store_true", help="Display numbers non-empty lines") +parser.add_argument("-n", action="store_true", help="Display all lines numbers") +parser.add_argument("-b", action="store_true", help="Display numbers non-empty lines") parser.add_argument("path", nargs="+", help="The file to search") args = parser.parse_args() @@ -19,13 +18,13 @@ if args.n: for line in content: print(f"{number}\t{line.strip()}") - number +=1 + number += 1 elif args.b: for line in content: - if line.strip() !="": + if line.strip() != "": print(f"{number}\t{line.strip()}") - number +=1 - else: + number += 1 + else: print("") else: - print("".join(content)) \ No newline at end of file + print("".join(content)) diff --git a/implement-shell-tools/wc/wc.py b/implement-shell-tools/wc/wc.py index 00989132..a29e7477 100644 --- a/implement-shell-tools/wc/wc.py +++ b/implement-shell-tools/wc/wc.py @@ -1,8 +1,7 @@ import argparse parser = argparse.ArgumentParser( - prog = "wc-count words, lines, characters", - description = "wc shell command on python" + prog="wc-count words, lines, characters", description="wc shell command on python" ) parser.add_argument("-l", action="store_true", help="Count lines") @@ -15,7 +14,7 @@ count_total_lines = 0 count_total_words = 0 -count_total_bytes = 0 +count_total_bytes = 0 for file_path in args.path: with open(file_path, "r") as file: @@ -23,41 +22,34 @@ count_lines = content.count("\n") count_words = len(content.split()) - count_bytes=len(content.encode("utf-8")) + count_bytes = len(content.encode("utf-8")) - count_total_lines += count_lines + count_total_lines += count_lines count_total_words += count_words - count_total_bytes += count_bytes + count_total_bytes += count_bytes if not (args.l or args.w or args.c): - print (count_lines, count_words, count_bytes, file_path) + print(count_lines, count_words, count_bytes, file_path) else: line = "" if args.l: line += f"{count_lines} " - if args.w: + if args.w: line += f"{count_words} " - if args.c: + if args.c: line += f"{count_bytes} " line += f"{file_path}" print(line) if len(args.path) > 1: if not (args.l or args.w or args.c): - print (count_total_lines, count_total_words, count_total_bytes, " total") + print(count_total_lines, count_total_words, count_total_bytes, " total") else: line = "" if args.l: line += f"{count_total_lines} " - if args.w: + if args.w: line += f"{count_total_words} " - if args.c: + if args.c: line += f"{count_total_bytes} " line += " total" print(line) - - - - - - - From 9bc06ec9e6ceec874c786a26b9604ccbc9a698f6 Mon Sep 17 00:00:00 2001 From: Nataliia Volkova Date: Tue, 13 Jan 2026 21:50:39 +0000 Subject: [PATCH 6/6] refactoring --- implement-shell-tools/wc/wc.py | 46 ++++++++++++++++------------------ 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/implement-shell-tools/wc/wc.py b/implement-shell-tools/wc/wc.py index a29e7477..cd69d4c9 100644 --- a/implement-shell-tools/wc/wc.py +++ b/implement-shell-tools/wc/wc.py @@ -11,23 +11,15 @@ args = parser.parse_args() - -count_total_lines = 0 -count_total_words = 0 -count_total_bytes = 0 - -for file_path in args.path: - with open(file_path, "r") as file: - content = file.read() +def calculate_counts(content): count_lines = content.count("\n") count_words = len(content.split()) count_bytes = len(content.encode("utf-8")) + + return count_lines, count_words, count_bytes - count_total_lines += count_lines - count_total_words += count_words - count_total_bytes += count_bytes - +def format_output(count_lines, count_words, count_bytes, file_path): if not (args.l or args.w or args.c): print(count_lines, count_words, count_bytes, file_path) else: @@ -40,16 +32,22 @@ line += f"{count_bytes} " line += f"{file_path}" print(line) + +count_total_lines = 0 +count_total_words = 0 +count_total_bytes = 0 + +for file_path in args.path: + with open(file_path, "r") as file: + content = file.read() + + count_lines, count_words, count_bytes = calculate_counts(content) + + count_total_lines += count_lines + count_total_words += count_words + count_total_bytes += count_bytes + + format_output(count_lines, count_words, count_bytes, file_path) + if len(args.path) > 1: - if not (args.l or args.w or args.c): - print(count_total_lines, count_total_words, count_total_bytes, " total") - else: - line = "" - if args.l: - line += f"{count_total_lines} " - if args.w: - line += f"{count_total_words} " - if args.c: - line += f"{count_total_bytes} " - line += " total" - print(line) + format_output(count_total_lines, count_total_words, count_total_bytes, " total")