Como eu procuro por substrings no Bash?

3

Eu quero descobrir e exibir a quantidade total de substrings TTT encontradas nas primeiras 2.000 linhas no arquivo.

Eu estava usando o grep até que eu o testei e percebi que ele não identifica substrings.

    
por noname 20.04.2016 / 01:42

2 respostas

1

Se você está procurando pela ocorrência de 3 caracteres "T" consecutivos em um arquivo, você pode fazer isso com o grep. O que você tentou que não funcionou? E, se você quiser apenas verificar as primeiras 2.000 linhas do arquivo, você pode canalizar a saída do arquivo. comando head no grep. Por exemplo, head -n 2000 somefile.txt | grep "TTT" Se você quiser uma contagem das linhas no arquivo que contém "TTT", poderá usar o seguinte:

head -n 2000 somefile.txt | grep -c "TTT"

Se algumas linhas puderem ter várias ocorrências e você quiser contar todas as ocorrências em vez de apenas o número de linhas contendo "TTT", use a opção -o para grep , que exibirá cada ocorrência em uma linha separada e depois canalizará a saída para o wc , que exibirá uma contagem de todas as ocorrências de "TTT" nas primeiras 2000 linhas do arquivo:

head -n 2000 somefile.txt | grep -o "TTT" | wc -l

    
por 20.04.2016 / 02:46
0

Explicação

Normalmente, pesquisar TTT (3 T's) em TTTTTT (6 T's) rende apenas 2 correspondências porque a pesquisa da próxima correspondência é feita logo após a correspondência anterior ser encontrada.

Vou tentar ilustrar:

TTTTTT
^ set starting position

TTTTTT
‾‾‾  found a match for TTT

TTTTTT
‾‾‾^ set next starting position

TTTTTT
   ‾‾‾  found a match for TTT

TTTTTT
      ^ end of stream

Solução

Se você quiser considerar TTTTTT como quatro instâncias de TTT , sugiro que corresponda apenas a um único caractere e use lookaround para completar seu padrão de correspondência.

Vou usar um lookahead na minha solução:

head -2000 file | /usr/gnu/bin/grep -P -o 'T(?=TT)' | wc -l

Explicações para a parte grep :

  • Use um grep que suporte a expressão regular Perl para usar lookahead; no meu sistema eu preciso especificar isso para /usr/gnu/bin/grep
  • -P para ativar o modo de expressão regular Perl
  • -o para exibir cada ocorrência em uma linha separada para permitir que wc -l conte cada correspondência
  • 'T(?=TT)' é uma expressão regular para corresponder a T , que é seguido por TT (usando uma lookahead); Depois de encontrar uma correspondência, o mecanismo de expressões regulares começará no segundo T para tentar encontrar a próxima correspondência, permitindo que essa segunda T faça parte o próximo jogo se estiver de acordo com o padrão.

Exemplo

Usando sua string de amostra do comentário:

  • JKHFSDTTTJSDJHTTTTTKSJTIITTT

e processando-o com o regex acima:

echo 'JKHFSDTTTJSDJHTTTTTKSJTIITTT' | /usr/gnu/bin/grep -P --color=always 'T(?=TT)'

produzirá:

  • JKHFSD T TTJSDJH TTT TTKSJTII T TT (ou seja, destacará 5 T's)

o que significa:

  • encontra 5 correspondências:)

Ilustração:

JKHFSDTTTJSDJHTTTTTKSJTIITTT
^ set starting position

JKHFSDTTTJSDJHTTTTTKSJTIITTT
      ‾^ found a match for T(?=TT) & set next starting position

JKHFSDTTTJSDJHTTTTTKSJTIITTT
              ‾^ found a match for T(?=TT) & set next starting position

JKHFSDTTTJSDJHTTTTTKSJTIITTT
               ‾^ found a match for T(?=TT) & set next starting position

JKHFSDTTTJSDJHTTTTTKSJTIITTT
                ‾^ found a match for T(?=TT) & set next starting position

JKHFSDTTTJSDJHTTTTTKSJTIITTT
                         ‾^ found a match for T(?=TT) & set next starting position

JKHFSDTTTJSDJHTTTTTKSJTIITTT
                            ^ end of stream
    
por 17.05.2016 / 15:26