Skip to content

Commit 6c1e6a5

Browse files
committed
wc
1 parent 17b2b5b commit 6c1e6a5

File tree

1 file changed

+63
-10
lines changed
  • implement-shell-tools/wc

1 file changed

+63
-10
lines changed

implement-shell-tools/wc/wc.py

Lines changed: 63 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,78 @@
11
import argparse
2+
import glob
23

34
def count_file(filename):
5+
line_count = 0
6+
word_count = 0
7+
byte_count = 0
8+
49
try:
5-
with open(filename, "r", encoding="utf-8") as f:
10+
with open(filename, "rb") as f:
611
content = f.read()
7-
lines = content.count("\n")
8-
words = len(content.split())
9-
bytes_ = len(content.encode("utf-8"))
10-
return lines, words, bytes_
12+
byte_count = len(content)
13+
text = content.decode("utf-8", errors="replace")
14+
lines = text.splitlines()
15+
line_count = len(lines)
16+
word_count = sum(len(line.split()) for line in lines)
17+
18+
return (line_count, word_count, byte_count)
1119
except FileNotFoundError:
1220
print(f"wc: {filename}: No such file or directory")
13-
return 0, 0, 0
21+
return None
1422

1523
def main():
1624
parser = argparse.ArgumentParser(description="Python version of wc")
17-
parser.add_argument("files", nargs="+", help="Files to count")
25+
parser.add_argument("-l", action="store_true", help="Count lines")
26+
parser.add_argument("-w", action="store_true", help="Count words")
27+
parser.add_argument("-c", action="store_true", help="Count bytes")
28+
parser.add_argument("files", nargs="+", help="Files to read (supports wildcards)")
1829
args = parser.parse_args()
1930

20-
for filename in args.files:
21-
lines, words, bytes_ = count_file(filename)
22-
print(f"{lines:7} {words:7} {bytes_:7} {filename}")
31+
# If no flag is given, show all
32+
show_lines = args.l
33+
show_words = args.w
34+
show_bytes = args.c
35+
if not (show_lines or show_words or show_bytes):
36+
show_lines = show_words = show_bytes = True
37+
38+
file_list = []
39+
for pattern in args.files:
40+
matched = glob.glob(pattern)
41+
if matched:
42+
file_list.extend(matched)
43+
else:
44+
file_list.append(pattern)
45+
46+
total_lines = total_words = total_bytes = 0
47+
for filename in file_list:
48+
result = count_file(filename)
49+
if result is None:
50+
continue
51+
lines, words, bytes_ = result
52+
total_lines += lines
53+
total_words += words
54+
total_bytes += bytes_
55+
56+
output = []
57+
if show_lines:
58+
output.append(f"{lines:7}")
59+
if show_words:
60+
output.append(f"{words:7}")
61+
if show_bytes:
62+
output.append(f"{bytes_:7}")
63+
output.append(filename)
64+
print(" ".join(output))
65+
66+
if len(file_list) > 1:
67+
output = []
68+
if show_lines:
69+
output.append(f"{total_lines:7}")
70+
if show_words:
71+
output.append(f"{total_words:7}")
72+
if show_bytes:
73+
output.append(f"{total_bytes:7}")
74+
output.append("total")
75+
print(" ".join(output))
2376

2477
if __name__ == "__main__":
2578
main()

0 commit comments

Comments
 (0)