On Fri, Jan 19, 2024 at 09:25:14AM +0100, Thomas Schmitt wrote:
> An answer to this question
>   
> https://stackoverflow.com/questions/16679369/count-occurrences-of-a-char-in-a-string-using-bash
> proposes
>     echo "referee" | tr -cd 'e' | wc -c
> 
>   $ echo ',,,' | tr -cd ',' | wc -c
>   3

That's one way, and it's sh-compatible.

If you actually want to do it in *bash* as the URL suggests, you can
take advantages of bash's extra features, to avoid forking two new
programs plus a subshell.

unicorn:~$ string="apple,banana,cherry,date"
unicorn:~$ commas=${string//[!,]/}
unicorn:~$ echo "${#commas}"
3

In this case, I'm using the ${varname//old/new} expansion to remove
everything that isn't a comma.

But at this point, we have to wonder what the *actual* goal is.  They
wanted to count the number of commas... why, exactly?  Are they going
to split the input string into a list of substrings?  If so, just do
that in the first place.

unicorn:~$ IFS=, read -ra list <<< "$string,"
unicorn:~$ declare -p list
declare -a list=([0]="apple" [1]="banana" [2]="cherry" [3]="date")

To understand why I added an extra comma at the end of the input
string, see <https://mywiki.wooledge.org/BashPitfalls#pf47>.

This approach needs adjustment if the input string may contain
newlines.  So, please state the actual goal up front, in full, and
include a worst-case-scenario example.

Finally, if the input is actually a CSV (Comma-Separated Values)
file, which may contain fields with commas *inside* them, then none
of these approaches work.  You need an actual CSV parser to handle
these files properly.

Reply via email to