1+ import { program } from "commander" ;
2+ import { promises as fs } from "node:fs" ;
3+
4+ program
5+ . name ( "mywc" )
6+ . description (
7+ "Counts lines, words, and bytes in files like the Unix wc command"
8+ )
9+ . option ( "-l" , "counts the number of lines" )
10+ . option ( "-w" , "counts words" )
11+ . option ( "-c" , "counts bytes" )
12+ . argument ( "<files...>" , "Files to count" ) ;
13+
14+ program . parse ( ) ;
15+
16+ const options = program . opts ( ) ;
17+ const files = program . args ;
18+
19+ // If there are no given flags, default to counting lines, words and bytes like the Unix wc command
20+ if ( ! options . l && ! options . w && ! options . c ) {
21+ options . l = true ;
22+ options . w = true ;
23+ options . c = true ;
24+ }
25+
26+ const showLines = options . l ;
27+ const showWords = options . w ;
28+ const showBytes = options . c ;
29+
30+ // To support multiple files and a total
31+ let totalLines = 0 ;
32+ let totalWords = 0 ;
33+ let totalBytes = 0 ;
34+
35+ for ( const file of files ) {
36+ try {
37+ const content = await fs . readFile ( file , "utf-8" ) ;
38+
39+ const lineCount = content . split ( "\n" ) . length - 1 ;
40+ const wordCount = content . trim ( ) . split ( / \s + / ) . filter ( Boolean ) . length ;
41+ const byteCount = Buffer . byteLength ( content , "utf-8" ) ;
42+
43+ totalLines += lineCount ;
44+ totalWords += wordCount ;
45+ totalBytes += byteCount ;
46+
47+ let output = "" ;
48+ if ( showLines ) output += `${ lineCount . toString ( ) . padStart ( 8 ) } ` ;
49+ if ( showWords ) output += `${ wordCount . toString ( ) . padStart ( 8 ) } ` ;
50+ if ( showBytes ) output += `${ byteCount . toString ( ) . padStart ( 8 ) } ` ;
51+ output += ` ${ file } ` ;
52+
53+ console . log ( output ) ;
54+ } catch ( err ) {
55+ console . error ( `Error reading file ${ file } : ${ err . message } ` ) ;
56+ }
57+ }
58+
59+ // If multiple files were given, show the total
60+ if ( files . length > 1 ) {
61+ let totalOutput = "" ;
62+ if ( showLines ) totalOutput += `${ totalLines . toString ( ) . padStart ( 8 ) } ` ;
63+ if ( showWords ) totalOutput += `${ totalWords . toString ( ) . padStart ( 8 ) } ` ;
64+ if ( showBytes ) totalOutput += `${ totalBytes . toString ( ) . padStart ( 8 ) } ` ;
65+ totalOutput += " total" ;
66+
67+ console . log ( totalOutput ) ;
68+ }
0 commit comments