Usando funções de processamento de strings, podemos fazer isso com o Perl da seguinte maneira:
printf '%s\n' "$STRING" |
perl -nse '
$_ .= join "", <>;
$k++ while ++($p = index($_, $s, $p));
print $k, "\n" ;
' -- -s="$SUB_STRING"
Explicação:
° load up the whole string in $_
° index function will return the position of a substring in a string OTW returns -1
° progressively match the substring and use the position found as the starting position for the next search.
° all this while increment the counter $k depicting substring found.
Alguns outros métodos estão listados abaixo:
Slurp a string e use regex.
printf '%s\n' "$STRING" |
perl -slp -0777e '
$_ = () = /$s/g;
' -- -s="$s"
° Slurp string na variável $ _.
° passa a substring da linha de comando para perl usando a opção -s.
° agora executa uma correspondência em $ _ e, em um contexto de lista, você recebe as correspondências que são obtidas no contexto escalar para obter o número de correspondências.
° a opção -p deve fazer automaticamente o que está em $ _.
Método usando a ferramenta sed:
esc_s=$(printf '%s\n' "$SUB_STRING" |\
sed -e 's:[][\/.^$*]:\&:g' -e 'H;1h;$!d;g;s/\n/\n/g')
printf '%s\n' "$STRING" |
sed -ne '
$!{N;s/^/\n/;D;}
/'"$esc_s"'/{
x;p;x
s///;s/^/\n/;D
}
' | wc -l
° Como uma etapa preparatória, vamos em frente e escapamos de todos os personagens agindo como meta-caracteres para o lado esquerdo da instrução s /// na subseqüência, o que, se não for feito, causará a queda do sed.
° Agora nós slurp o todo da corda no espaço do teste padrão.
° então continuamos imprimindo uma linha vazia, o espaço de espera é um bom candidato e retiramos a substring do espaço de padrão.
° enxágüe ... espuma ... repita enquanto a substring estiver presente.
° as linhas vazias são então canalizadas para a ferramenta wc que nos dará a contagem de linhas = número de vezes que a substring foi encontrada.
Esta é a versão do shell:
e=$STRING N=0
while
e=$(expr " $e" : " \(.*\)$SUB_STRING")
case $e in "" ) break ;; esac
do
N=$(expr "$N" + 1)
done
echo "$N"