Word count (Lua)
From LiteratePrograms
- Other implementations: Assembly Intel x86 Linux | C | C++ | Forth | Haskell | J | Lua | OCaml | Perl | Python | Python, functional | Rexx
An implementation of the UNIX wc tool in Lua.
The wc tool counts characters, words and lines in text files or stdin. When invoked without any options, it will print all three values. These options are supported:
- -c - Only count characters
- -w - Only count words
- -l - Only count lines
If the tool is invoked without any file name parameters, it will use stdin.
<<wc.lua>>= #!/usr/bin/env lua tot_chars=0 tot_words=0 tot_lines=0 opts="" printwc wc
Command line
First we read all options (arguments starting with '-'). Unrecoginzed options are ignored.
If the user did not provide any options, we use the default, "lwc", so that line-, word- and character-count are printed.
<<wc.lua>>= nfiles=0 for i=1,table.getn(arg) do if(nfiles==0 and string.sub(arg[i], 1, 1)=='-') then opts=opts .. arg[i] else if(string.len(opts)==0) then opts="lwc" end wc(arg[i]) nfiles=nfiles+1 end end
If no files where specified nfiles<1, we call wc() with "-", indicating we want to read from stdin. If there was more than one file, the sum of all files are printed.
<<wc.lua>>= if(string.len(opts)==0) then opts="lwc" end if nfiles<1 then wc("-") end if nfiles>1 then printwc(tot_lines, tot_words, tot_chars, "total") end
wc()
The wc() function does the counting work. It takes a file name as it only argument.
<<wc>>= function wc(fname) chars=0 words=0 lines=0 if(fname=="-") then it=io.lines() else it=io.lines(fname) end for line in it do lines=lines+1 for word in string.gfind(line, "[^%s]+") do words=words+1 end chars=chars+string.len(line)+1 end
When the counting is done, the the printwc() is used to print the result, and the global tot_... variables are updated.
<<wc>>= printwc(lines, words, chars, fname) tot_chars=tot_chars+chars tot_words=tot_words+words tot_lines=tot_lines+lines end
printwc()
printwc() uses the global opts variable to decide which values to print.
<<printwc>>= function printwc(lines, words, chars, fname) if(string.find(opts, "l")) then io.write(string.format("% 8d", lines)) end if(string.find(opts, "w")) then io.write(string.format("% 8d", words)) end if(string.find(opts, "c")) then io.write(string.format("% 8d", chars)) end if(fname~="-") then io.write(" "); print(fname) else print() end end
Download code |