Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have a list of words like this, separated by line:


And I have some files under a directory:

$ tree
|-- a.txt
|-- b.txt
|-- c.txt
|-- d
|   |-- a.txt
|   |-- b.txt
|   |-- c.txt
|   |-- d.txt
|   |-- e.txt
|   |-- f.txt
|   `-- g.txt

How can I count the occurrences of words in those files? Output should be like:

Range: 0
Balance: 32
Total: 100
CombinRow: 3
GridKey: 1
KeDanJia: 43
AddRowNum: 5
TopList: 34
Keysearch: 0
Keysearchtaobao: 1
IsearchData: 12
IsearchDataSep: 123
share|improve this question
Do you have excel? – soandos Aug 3 '11 at 2:28
No, I only have a remote shell. – fool Aug 3 '11 at 2:33
up vote 5 down vote accepted

Assuming your list of words is in a file called /path/to/words.txt and your tree is located at /tree for the purposes of this example, try:

find /tree -name '*.txt' -execdir sed 's/ /\
/g' {} + | grep -Fw -f /path/to/words.txt | sort | uniq -c | \
awk '{print $2 ": " $1}'
share|improve this answer
After reading John's answer I realized that both his and my original answers only count line frequencies so if a word appears multiple times in a line the count would be incorrect. My updated answer has the following changes: use sed to split input files one word per line and add -w option to grep so for example Range in words.txt will not match Ranger. – jw013 Aug 3 '11 at 5:59
awk '
  FILENAME == ARGV[1] {word[$0]=0; next}
    for (i=1; i<=NF; i++) {
      if ($i in word) word[$i]++
  END {for (w in word) print w ": " word[w]}
' word.file $(find . -type f -print)
share|improve this answer

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .