Reputation: 35
I'd like to count the number of occurrences in a string. For example, in this string :
'apache2|ntpd'
there are 2 different strings separated by |
character.
Another example :
'apache2|ntpd|authd|freeradius'
In this case there are 4 different strings separated by |
character.
Would you know a shell or perl command that could simply count this for me?
Upvotes: 1
Views: 90
Reputation: 15461
With wc
and parameter expansion:
$ data='apache2|ntpd|authd|freeradius'
$ wc -w <<< ${data//|/ }
4
Using parameter expansion, all pipes are replaced with spaces. The result string is passed to wc -w
for word count.
As @gniourf_gniourf mentionned, it works with what at first looks like process names but will fail if strings contain spaces.
Upvotes: 1
Reputation: 4112
you can use awk command as below;
echo "apache2|ntpd" | awk -F'|' '{print NF}'
-F'|' is to field separator; NF means Number of Fields
Example;
user@host:/tmp$ echo 'apache2|ntpd|authd|freeradius' | awk -F'|' '{print NF}'
4
you can also use this;
user@host:/tmp$ echo "apache2|ntpd" | tr '|' ' ' | wc -w
2
user@host:/tmp$ echo 'apache2|ntpd|authd|freeradius' | tr '|' ' ' | wc -w
4
tr '|' ' ' : translate | to space
wc -w : print the word counts
if there are spaces in the string, wc -w not correct result, so
echo 'apac he2|ntpd' | tr '|' '\n' | wc -l
user@host:/tmp$ echo 'apac he2|ntpd' | tr '|' ' ' | wc -w
3 --> not correct
user@host:/tmp$ echo 'apac he2|ntpd' | tr '|' '\n' | wc -l
2
tr '|' '\n' : translate | to newline
wc -l : number of lines
Upvotes: 3
Reputation: 2503
may be this will help you.
IN="apache2|ntpd"
mails=$(echo $IN | tr "|" "\n")
for addr in $mails
do
echo "> [$addr]"
done
Upvotes: -1
Reputation: 37404
You could use awk to count the occurrances of delimiters +1:
$ awk '{print gsub(/\|/,"")+1}' <(echo "apache2|ntpd|authd|freeradius")
4
Upvotes: 0
Reputation: 1770
You can do this with grep
as well-
echo "apache2|ntpd|authd|freeradius" | grep -o "|" | wc -l
Output-
3
That output is the number of pipes.
To get the number of commands-
var=$(echo "apache2|ntpd|authd|freeradius" | grep -o "|" | wc -l)
echo $((var + 1))
Output -
4
Upvotes: 0
Reputation: 85580
Another pure bash
technique using positional-parameters
$ userString="apache2|ntpd|authd|freeradius"
$ printf "%s\n" $(IFS=\|; set -- $userString; printf "%s\n" "$#")
4
Thanks to cdarke's suggestion from the commands, the above command can directly store the count to a variable
$ printf -v count "%d" $(IFS=\|; set -- $userString; printf "%s\n" "$#")
$ printf "%d\n" "$count"
4
Upvotes: 1
Reputation: 44354
Do can do this just within bash
without calling external languages like awk
or external programs like grep
and tr
.
data='apache2|ntpd|authd|freeradius'
res=${data//[!|]/}
num_strings=$(( ${#res} + 1 ))
echo $num_strings
Let me explain.
res=${data//[!|]/}
removes all characters that are not (that's the !
) pipes (|
).
${#res}
gives the length of the resulting string.
num_strings=$(( ${#res} + 1 ))
adds one to the number of pipes to get the number of fields.
It's that simple.
Upvotes: 1