I want to make a Unix command that reads a string and counts how many words it contains. In my case the words are separated by a _ (underscore) character, not spaces.

For example, TABLE_PERSON contains two words, so the command should print "2".

How can I do that?

  • Hi user316467. I have edited your question to remove superfluous material not directly related to the question that you are asking. Should you feel that my edit changed the intent of your question, feel free to either roll back (click the "edited" link, then click "rollback" next to the revision you wish to roll back to) or edit further. – a CVn May 22 '14 at 19:16

If your string does not contain spaces you can substitute the _ with a space (with tr (translate character) or sed (stream editor)) and use wc (word count) to count the words:

 $ echo TABLE_PERSON | tr '_' ' ' | wc -w


 $ echo TABLE_PERSON | sed 's/_/ /' | wc -w

if your string contains spaces which do not have to be considered as a separator (e.g., if "TABLE_PERSON 2" counts as two words separated by _: TABLE and PERSON 2) you can first remove the spaces with any character (e.g., -) and use the same command:

 $ echo 'TABLE_PERSON 2' | tr ' ' '-' | tr '_' ' ' | wc -w
  • Hi @user316467. If you found this answer helpful in answering your question, consider upvoting it by clicking the up arrow in the left-hand column. If you feel this answer properly addresses all your concerns or was instrumental in resolving your issue, consider accepting it by clicking the checkmark outline in the left-hand column, below the voting arrows. Accepting an answer informs the community that you feel your issue has been resolved, and is the customary way of saying thank you on Super User and the Stack Exchange network. – a CVn May 22 '14 at 19:31

Many ways, most of which are easy to figure out:

n=$(tr -dc "_" | wc -c)
echo $((n+1))
tr " _" "x " | wc -w
#!/usr/bin/env bash
read -r string
echo $((len1-len2+1))
#!/usr/bin/env perl
print (scalar split /_/, <STDIN>)."\n";
#!/usr/bin/env python3
import sys
#!/usr/bin/env ruby
puts gets.split(/_/).length
#include <stdio.h>
int main(void) {
    int c, n = 1;
    for (;;) {
        c = getchar();
        if (c == EOF || c == '\n')
        else if (c == '_')
    printf("%u\n", n);
    return 0;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.