Como posso contar o número de ocorrências de uma substring em uma string usando o Bash?
EXEMPLO:
Gostaria de saber quantas vezes essa substring ...
Bluetooth
Soft blocked: no
Hard blocked: no
... ocorre nesta cadeia ...
0: asus-wlan: Wireless LAN
Soft blocked: no
Hard blocked: no
1: asus-bluetooth: Bluetooth
Soft blocked: no
Hard blocked: no
2: phy0: Wireless LAN
Soft blocked: no
Hard blocked: no
113: hci0: Bluetooth
Soft blocked: no
Hard blocked: no
NOTA I: Tentei várias abordagens com sed, grep, awk ... Nada parece funcionar quando temos strings com espaços e várias linhas.
NOTA II: Eu sou um usuário Linux e estou tentando uma solução que não envolve a instalação de aplicativos / ferramentas fora daqueles que normalmente são encontrados nas distribuições Linux.
IMPORTANTE:
Eu gostaria de algo como o exemplo hipotético abaixo. Nesse caso, usamos duas variáveis de shell (Bash) .
EXEMPLO:
STRING="0: asus-wlan: Wireless LAN
Soft blocked: no
Hard blocked: no
1: asus-bluetooth: Bluetooth
Soft blocked: no
Hard blocked: no
2: phy0: Wireless LAN
Soft blocked: no
Hard blocked: no
113: hci0: Bluetooth
Soft blocked: no
Hard blocked: no"
SUB_STRING="Bluetooth
Soft blocked: no
Hard blocked: no"
awk -v RS='\0' 'NR==FNR{str=$0; next} {print gsub(str,"")}' "$STRING" "$SUB_STRING"
NOTA: Estamos usando o awk apenas para ilustrar!
bash
shell
shell-script
bash-scripting
Eduardo Lucio
fonte
fonte
Respostas:
Suponho que isso possa ser melhorado
awk
, mas é o melhor que posso oferecer.-z
fazgrep
tratar o arquivo inteiro como uma linha.-o
grava apenas a saída que corresponde à string e não à linha inteira.(no nosso caso, com
-z
isso significa o arquivo inteiro)\s
corresponde a caracteres em branco e novas linhas.A segunda instância de
grep
pesquisará apenas a palavra "Bluetooth" na saída da primeiragrep
chamada.-c
fazgrep
escrever a contagem de regex correspondente, em vez de corresponder a si próprio.fonte
Não está claro como você gostaria de corresponder (seu exemplo adicional no comentário acima não lança nenhuma luz), no entanto, suponha que você armazene seu bloco de strings com as informações de rede dentro de um arquivo
string
e o bloco de substring dentro de um arquivosubstring
.Usando a seguinte abordagem, você obteria o que eu entendo que você esperava: 2 correspondências.
Essencialmente, as duas seqüências são condensadas em uma linha, ignorando espaços em branco ou tabulações e convertendo novas linhas em
@
. Usando agrep -o
sintaxe, imprimimos todas as ocorrências (-o
) do padrão encontrado.No entanto, não está claro se, no seu exemplo, você espera que ele corresponda a 0 vezes (correspondência posicional exata) ou 2 vezes (ignorando o texto anexado). Esta é uma solução muito semelhante à que Iskustvo postou aqui ; será que não entendemos sua intenção?
Se você estiver tentando contar correspondências de um fragmento de texto bidimensional, provavelmente precisará de grep difuso.
fonte