Skip to content

Commit 4debef1

Browse files
committed
add wc tool with line, word, and byte counting
1 parent 310c2ad commit 4debef1

File tree

1 file changed

+106
-0
lines changed
  • implement-shell-tools/wc

1 file changed

+106
-0
lines changed

implement-shell-tools/wc/wc.py

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
#!/usr/bin/env python3
2+
3+
import argparse
4+
import sys
5+
import os
6+
7+
parser = argparse.ArgumentParser(
8+
prog="wc",
9+
description="Simple reimplementation of wc"
10+
)
11+
12+
parser.add_argument(
13+
"-l",
14+
dest="count_lines",
15+
action="store_true",
16+
help="Print the line counts"
17+
)
18+
19+
parser.add_argument(
20+
"-w",
21+
dest="count_words",
22+
action="store_true",
23+
help="Print the word counts"
24+
)
25+
26+
parser.add_argument(
27+
"-c",
28+
dest="count_bytes",
29+
action="store_true",
30+
help="Print the byte counts"
31+
)
32+
33+
parser.add_argument(
34+
"paths",
35+
nargs="+",
36+
help="File(s) to process"
37+
)
38+
39+
args = parser.parse_args()
40+
41+
42+
def wc_file(path):
43+
"""Return (lines, words, bytes) for a file."""
44+
try:
45+
with open(path, "r", encoding="utf-8") as f:
46+
content = f.read()
47+
except FileNotFoundError:
48+
sys.stderr.write(f"wc: {path}: No such file or directory\n")
49+
return None
50+
51+
lines = content.count("\n") + (1 if content and not content.endswith("\n") else 0)
52+
words = len(content.split())
53+
bytes_ = len(content.encode("utf-8"))
54+
55+
return lines, words, bytes_
56+
57+
58+
# If no flags are supplied, show all three
59+
show_all = not (args.count_lines or args.count_words or args.count_bytes)
60+
61+
totals = [0, 0, 0] # lines, words, bytes
62+
multiple_files = len(args.paths) > 1
63+
64+
for path in args.paths:
65+
result = wc_file(path)
66+
if result is None:
67+
continue
68+
69+
lines, words, bytes_ = result
70+
71+
totals[0] += lines
72+
totals[1] += words
73+
totals[2] += bytes_
74+
75+
output_parts = []
76+
77+
if show_all:
78+
output_parts.extend([str(lines), str(words), str(bytes_)])
79+
else:
80+
if args.count_lines:
81+
output_parts.append(str(lines))
82+
if args.count_words:
83+
output_parts.append(str(words))
84+
if args.count_bytes:
85+
output_parts.append(str(bytes_))
86+
87+
output_parts.append(path)
88+
print(" ".join(output_parts))
89+
90+
91+
# If multiple files → print total line
92+
if multiple_files:
93+
totals_output = []
94+
95+
if show_all:
96+
totals_output.extend([str(totals[0]), str(totals[1]), str(totals[2])])
97+
else:
98+
if args.count_lines:
99+
totals_output.append(str(totals[0]))
100+
if args.count_words:
101+
totals_output.append(str(totals[1]))
102+
if args.count_bytes:
103+
totals_output.append(str(totals[2]))
104+
105+
totals_output.append("total")
106+
print(" ".join(totals_output))

0 commit comments

Comments
 (0)