How does d=${c//[^$b]} count how many times the letter $b is found in $c?

Viewed 51
#!/bin/bash

echo "The program checks the number of indicated letters"
echo "Enter the file name and path"
read a
c=$(cat $a)
echo "
Enter which letter is to be found. for examle 'a' "
read b
d=${c//[^$b]}
echo "The number of occurrences of the character is: " ${#d}

I can't understand how this line works: d=${c//[^$b]}. The program works fine, I just don't understand how the expression [^$b] works. I have read that the expression [^...] matches any characters that are not in parentheses.

For example, if the user enters the character 'a', he will find the number of occurrences of this letter in the indicated file. Could someone help me and explain how this works because the definition [^...] says something completely different.

I found such a definition: "[^d]" matches any character except those in the range b through d. So if there are strings of sentences in the file that contain and shouldn't show them like this, unless I misunderstand something.

1 Answers

${s//x} will remove all occurrences of x in the value of variable s. [x] will match any character in the list (the list contains a single character only, so only "x" will be matched). [^x] matches all characters except "x".

Therefore, ${a//[^x]} will only leave the "x" characters in the value. ${#v} gives the number of characters in the variable. Since only "x" characters are left in the variable, this gives you the number of those characters.

It's also possible to achieve the same by calling external programs and not only relying on bash variable expansion (IMO a bit more straightforward and expresses the intent more clearly):

echo "The number of occurrences of the character is: $(grep -oe "[$b]" "$a" | wc -l)"
Related