Bash command to check number of words in a file that contain letter “a”


5 Answers 5


Suppose that we have this test file:

$ cat file
the cat in the hat
the quick brown dog
jack splat

With grep implementations that have adopted GNU's -o extension, we can retrieve all the words containing a:

$ grep -wo '[[:alnum:]]*a[[:alnum:]]*' file

We can count those words:

$ grep -wo '[[:alnum:]]*a[[:alnum:]]*' file | wc -l
  • 1
    Personally I would consider using grep -c and would also use [aA] or the -i flag to ensure that words with an upper case A are also counted. Aug 2, 2015 at 14:25
  • Adding -i for case-insensitivity is a good idea. -c counts the number of matching lines of input, not matching words in the output. For example, with the input file above, grep -woc '[[:alnum:]]*a[[:alnum:]]*' file returns 2 because there are two matching lines. By contrast, grep -wo '[[:alnum:]]*a[[:alnum:]]*' file | grep -c . would give the correct answer. Alternatively, @yaegashi's approach shows a good use of grep -c.
    – John1024
    Aug 2, 2015 at 19:49


<file tr -s '[:space:]' '[\n*]' | grep -c a

Here, words are sequences of non-spacing characters.


Here's a Perl way:

 perl -0lnE 'say scalar grep(/a/,split(/\s/,$_));' file

And an awk way:

 awk '{for(i=1;i<=NF;i++){if($(i)~/a/){k++}}}END{print k}' file
  • 1
    Won't that just give you the number of a's in the file rather than the number of words containing a? Aug 1, 2015 at 19:01
  • @Colin'tHart um. Yes. Indeed it will. Thanks, no idea what I was thinking there.
    – terdon
    Aug 1, 2015 at 19:24

With GNU grep:

 grep -oP '\b\w*a+\w*\b' file
awk 'BEGIN{RS="[[:space:][:punct:]]"; c=0}
     END{print c}'

Using a version of awk that supports multi-character Record Separator (RS), eg. GNU awk, you can cause awk to read one word per record.

Within that record, the index(in, string) function searches in for the first occurrence of string, and returns the 1-based character position of where it is found. If not found, index() returns 0. Thus the return value can be treated as a boolean condition test (0 = false, not zero = true). Note, this is not a regular expression search.

If a match is found, the variable c is incremented by 1 (c++)

The c=0 is required in the BEGIN{} block, for when c is never incremented - which would cause c to be null instead of 0. Another way to handle this issue would be to print 0+c (in the END{} block)

  • 2
    This relies on a version of awk that supports multi-character RS (e.g. GNU awk). I would probably put a + at the end of the pattern [[:space:][:punct:]]+ to match one or more characters and just use /a/{c++} (although I guess index might be marginally quicker). Some explanation would make your answer more useful.
    – Tom Fenech
    Aug 1, 2015 at 14:55

You must log in to answer this question.

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