Skip to content

Commit 4969b17

Browse files
committed
Implementing cat with a python script.
1 parent 407b010 commit 4969b17

1 file changed

Lines changed: 62 additions & 0 deletions

File tree

  • implement-shell-tools/cat

implement-shell-tools/cat/cat.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import argparse
2+
import sys
3+
import glob # to find file paths and match patterns
4+
5+
6+
7+
def parse_args():
8+
parser = argparse.ArgumentParser(
9+
prog = "cat",
10+
description= "copying cat commands behavior with -n and -b flags"
11+
)
12+
parser.add_argument("-n", "--number", action="store_true", help="Number all output lines") #with store true argument behaves like a boolean, flag present returns true, not present = false.
13+
parser.add_argument("-b", "--number-nonblank", action="store_true", help="Number non-empty output lines")
14+
parser.add_argument("files", nargs="+", help="Files to read (supports shell globs)") # accepts one or more files names or glob patterns.
15+
return parser.parse_args()
16+
17+
#Uses glob to expand patterns like *.txt.
18+
def expand_files(patterns):
19+
expanded = []
20+
for p in patterns:
21+
matches = glob.glob(p)
22+
if matches:
23+
expanded.extend(sorted(matches)) # predictable order
24+
else:
25+
print(f"cat: {p}: No such file", file=sys.stderr) #Prints an error if a pattern matches nothing.
26+
return expanded
27+
28+
def cat_file(filename, number_all=False, number_nonempty=False):
29+
try:
30+
with open(filename, 'r') as f:
31+
lines = f.readlines()
32+
except FileNotFoundError:
33+
print(f"cat: {filename}: No such file")
34+
return
35+
#Applies numbering rules depending on flags.
36+
line_num = 1
37+
for line in lines:
38+
line = line.rstrip('\n')
39+
if number_all:
40+
print(f"{line_num:6} {line}")
41+
line_num += 1
42+
elif number_nonempty:
43+
if line.strip():
44+
print(f"{line_num:6} {line}")
45+
line_num+= 1
46+
else:
47+
print(line)
48+
else:
49+
print(line)
50+
51+
def main():
52+
args = parse_args() #return an args obj
53+
files = expand_files(args.files) #list of filenames or patterns user typed passed to expand_files helper that uses glob module to expand patterns to actual file paths
54+
if not files:
55+
sys.exit(1) #programs exits with status code 1- signals and error if no files were found
56+
57+
#looping through each file path on expanded list
58+
for file in files:
59+
cat_file(file, number_all=args.number, number_nonempty=args.number_nonblank)
60+
61+
if __name__ == "__main__":
62+
main()

0 commit comments

Comments
 (0)