Shell, 8989 86 bytes
grep -io "[a-z0-9'-]*"|sort -f|uniq -ci|sort -nr|awk 'c{if(c>$1)print w;exit}{c=$1;w=$2}'
grep -io "[a-z0-9'-]*"|sort -f|uniq -ci|sort -nr|awk 'c>$1{print w}c{exit}{c=$1;w=$2}'
grep -io "[a-z0-9'-]*" # get a list of the words, one per line
|sort -f # sort (case insensitive, "folded")
|uniq -ci # count unique entries while still ignoring case
|sort -nr # sort counted data in descending order
|awk '
c { # if c (the most common word's count) is defined yet
if (c > $1) # if line 1's word was more common than line 2's
print w
exit # we always exit on line 2
}
{ # this stanza always runs (unless we have exited)
c = $1 # define c as the count of the first line's word
w = $2 # define w as the word itself
}'
grep -io "[a-z0-9'-]*" # get a list of the words, one per line
|sort -f # sort (case insensitive, "folded")
|uniq -ci # count unique entries while still ignoring case
|sort -nr # sort counted data in descending order
|awk '
count > $1 { # if count of most common word exceeds that of this line
print word # print the word saved from it
}
count { # if we have already saved a count (-> we are on line 2)
exit # we always exit on line 2 since we have enough info
}
{ # if true (run on line 1 only due to the above exit)
count = $1 # save the count of the word on this first line
word = $2 # save the word itself
}'
grep -o
is the magic tokenizer here. It takes each word (as defined by the given regular expression, case insensitive given -i
) and puts it on its own line.
alias cnt='sort -f |uniq -ci |sort -nr'
is an old standby of mine. Without regards to case, it alphabetizes (erm, asciibetizes) the lines of the input counts occurrences of each entry, then reverse-sorts by the numeric occurrences so the most popular is first.
awk
only looks at the first two lines of that descending ranked list. On line one, count
is not yet defined, so it is evaluated as zero and therefore the first two stanzas are skipped (zero == false). The third stanza sets count
and word
. On the second line, awk
has a defined and nonzero value for count
, so it compares that count to the second best count. If it's not tied, the saved word
is printed. Regardless, the next stanza exits for us.
Test implemented as:
for s in "The man walked down the road." "Slowly, he ate the pie, savoring each delicious bite. He felt like he was truly happy." "This sentence has no most frequent word." "\"That's... that's... that is just terrible\!\" he said." "The old-fashioned man ate an old-fashioned cake." "IPv6 looks great, much better than IPv4, except for the fact that IPv6 has longer addresses." "This sentence with words has at most two equal most frequent words."; do printf "%s\n==> " "$s"; echo "$s" |grep -io "[a-z0-9'-]*"|sort -f|uniq -ci|sort -nr|awk 'c{if(c>$1)print w;exit}{c=$1;w=$2}'; echo; done
for s in "The man walked down the road." "Slowly, he ate the pie, savoring each delicious bite. He felt like he was truly happy." "This sentence has no most frequent word." "\"That's... that's... that is just terrible\!\" he said." "The old-fashioned man ate an old-fashioned cake." "IPv6 looks great, much better than IPv4, except for the fact that IPv6 has longer addresses." "This sentence with words has at most two equal most frequent words."; do printf "%s\n==> " "$s"; echo "$s" |grep -io "[a-z0-9'-]*"|sort -f|uniq -ci|sort -nr|awk 'c>$1{print w}c{exit}{c=$1;w=$2}'; echo; done