A solution that calls several programs from a shell:
fmt -1 words.txt | sort -u | xargs -Ipattern sh -c 'echo "pattern:$(grep -cw pattern words.txt)"'
A little explanation:
fmt -1 words.txt prints out all the words, 1 per line, and the
| sort -u sorts this output and extracts only the unique words from it.
In order to count the occurences of a word in a file, one can use
grep (a tool meant to search files for patterns). By passing the
-cw option, grep gives the number of word matches it finds. So you can find the total number of occurrences of
grep -cw pattern words.txt.
xargs allows us to do this for each and every single word output by
-Ipattern means that it will execute the following command multiple times, replacing each occurrence of pattern with a word it reads from standard input, which is what it gets from
The indirection with
sh is needed because
xargs only knows how to execute a single program, given it's name, passing everything else as arguments to it.
xargs does not handle things like command substitution. The
$(...) is command substitution in the above snippet, as it substitutes the output from
echo, allowing it to be formatted correctly. Since we need the command substitution, we must use the
sh -c command which runs whatever it recieves as an argument in its own shell.