22import argparse
33
44def read_and_output_files ():
5- # 1. Setup Argument Parser (Equivalent to 'commander')
5+ # Setup Argument Parser (Equivalent to 'commander')
66 parser = argparse .ArgumentParser (description = "Python implementation of a basic cat-like utility" )
77 parser .add_argument ("-n" , "--number" , action = "store_true" , help = "number all output lines" )
88 parser .add_argument ("-b" , "--number-nonblank" , action = "store_true" , help = "number only non-empty lines" )
99 parser .add_argument ("files" , nargs = "+" , help = "files to read" )
1010
1111 args = parser .parse_args ()
1212
13- try :
14- # 2. Read all file contents (Equivalent to Promise.all / fs.readFile)
15- file_contents = []
16- for file_path in args .files :
17- with open (file_path , "r" , encoding = "utf-8" ) as f :
18- file_contents .append (f .read ())
19-
20- concatenated_content = "" .join (file_contents )
21-
22- # 3. Process Logic
23- if args .number :
24- # -n logic: number all lines
25- lines = concatenated_content .split ("\n " )
26- output = []
27- for index , line in enumerate (lines , start = 1 ):
28- # rjust(6) is equivalent to padStart(6)
29- output .append (f"{ str (index ).rjust (6 )} { line } " )
30- sys .stdout .write ("\n " .join (output ))
31-
32- elif args .number_nonblank :
33- # -b logic: number only non-empty lines
34- lines = concatenated_content .split ("\n " )
35- output = []
36- nonblank_line_number = 0
37- for line in lines :
38- if line .strip () == "" :
39- output .append (line )
40- else :
41- nonblank_line_number += 1
42- output .append (f"{ str (nonblank_line_number ).rjust (6 )} { line } " )
43- sys .stdout .write ("\n " .join (output ))
13+ line_number = 1
4414
45- else :
46- # No flags: standard output
47- sys .stdout .write (concatenated_content )
48-
49- except Exception as err :
50- print (f"Error reading multiple files: { err } " , file = sys .stderr )
51- sys .exit (1 )
15+ for file_path in args .files :
16+ try :
17+ with open (file_path , "r" , encoding = "utf-8" ) as f :
18+ for line in f :
19+ # 1. Handle -b logic (number only non-blank lines)
20+ if args .number_nonblank :
21+ # A truly blank line is JUST a newline character (\n or \r\n)
22+ if line == "\n " or line == "\r \n " :
23+ sys .stdout .write (line )
24+ else :
25+ # Standard cat uses a tab (\t) after the line number
26+ sys .stdout .write (f"{ str (line_number ).rjust (6 )} \t { line } " )
27+ line_number += 1
28+
29+ # 2. Handle -n logic (number all lines)
30+ elif args .number :
31+ sys .stdout .write (f"{ str (line_number ).rjust (6 )} \t { line } " )
32+ line_number += 1
33+
34+ # 3. Handle standard output
35+ else :
36+ sys .stdout .write (line )
37+
38+ except Exception as err :
39+ print (f"cat: { file_path } : { err } " , file = sys .stderr )
5240
5341if __name__ == "__main__" :
54- read_and_output_files ()
42+ read_and_output_files ()
0 commit comments