Yogesh Ralebhat
Yogesh Ralebhat

Reputation: 1466

How to count number of words from String using shell

I want to count number of words from a String using Shell.

Suppose the String is:

input="Count from this String"

Here the delimiter is space ' ' and expected output is 4. There can also be trailing space characters in the input string like "Count from this String ".

If there are trailing space in the String, it should produce the same output, that is 4. How can I do this?

Upvotes: 80

Views: 153285

Answers (9)

Kevin Davies
Kevin Davies

Reputation: 323

Use a simple function to count words in bash

$ count() { echo $#; }

$ s="is this really simple"
$ count $s
4

$ s="now sure"
$ count $s
2

$ p=$(count $s)
$ echo $p
2

Upvotes: 0

peter
peter

Reputation: 35

function count_item() {
   return $#
}
input="one two three"
count_item $input
n=$?
echo $n

NOTE: function parameter passing treat space as separated argument, therefore $# works. $? is the return value of the recently called function.

Upvotes: 2

sir__finley
sir__finley

Reputation: 160

It is efficient external command free way, like @dogbane's. But it works correctly with stars.

$ input="Count from *"
$ IFS=" " read -r -a words <<< "${input}"
$ echo ${#words[@]}
3

If input="Count from *" then words=( $input ) will invoke glob expansion. So size of words array will vary depending on count of files in current directory. So we use IFS=" " read -r -a words <<< "${input}" instead it.

see https://github.com/koalaman/shellcheck/wiki/SC2206

Upvotes: 0

qneill
qneill

Reputation: 1704

To do it in pure bash avoiding side-effects, do it in a sub-shell:

$ input="Count from this string "
$ echo $(IFS=' '; set -f -- $input; echo $#)
4

It works with other separators as well:

$ input="dog,cat,snake,billy goat,horse"
$ echo $(IFS=,; set -f -- $input; echo $#)
5
$ echo $(IFS=' '; set -f -- $input; echo $#)
2

Note the use of "set -f" which disables bash filename expansion in the subshell, so if the caller wants expansion it should be done beforehand (Hat Tip @mkelement0).

Upvotes: 9

AAAfarmclub
AAAfarmclub

Reputation: 2360

I'll just chime in with a perl one-liner (avoiding 'useless use of echo'):

perl -lane 'print scalar(@F)' <<< $input

Upvotes: 1

kenorb
kenorb

Reputation: 166359

Try the following one-liner:

echo $(c() { echo $#; }; c $input)

It basically defines c() function and passes $input as the argument, then $# returns number of elements in the argument separated by whitespace. To change the delimiter, you may change IFS (a special variable).

Upvotes: 12

Henry Barber
Henry Barber

Reputation: 133

echo "$input" | awk '{print NF}'

Upvotes: 6

Tuxdude
Tuxdude

Reputation: 49473

echo "$input" | wc -w

Use wc -w to count the number of words.

Or as per dogbane's suggestion, the echo can be got rid of as well:

wc -w <<< "$input"

If <<< is not supported by your shell you can try this variant:

wc -w << END_OF_INPUT
$input
END_OF_INPUT

Upvotes: 113

dogbane
dogbane

Reputation: 274532

You don't need an external command like wc because you can do it in pure bash which is more efficient.

Convert the string into an array and then count the elements in the array:

$ input="Count from this String   "
$ words=( $input )
$ echo ${#words[@]}
4

Alternatively, use set to set positional parameters and then count them:

$ input="Count from this String   "
$ set -- $input
$ echo $#
4

Upvotes: 60

Related Questions