Como . é um curinga da regex, grep '..' corresponde a cada
linha que tem pelo menos dois caracteres:
$ echo "$gene" | grep '..'
gene 89..1483
/gene="non-structural protein"
/gene="non-structural protein"
/gene="non-structural protein"
/gene="non-structural protein"
/gene="non-structural protein"
/gene="non-structural protein"
/gene="non-structural protein"
gene complement(1987..2763)
/gene="nucleocapsid protein"
/gene="nucleocapsid protein"
Nas expressões regulares, . é realmente selvagem: ele corresponderá não apenas a qualquer letra ou número, mas também a qualquer pontuação, em branco, tabulação ou qualquer outro caractere.
Para corresponder apenas a períodos, use -F :
$ echo "$gene" | grep -F '..'
gene 89..1483
gene complement(1987..2763)
-F é a abreviação de --fixed-strings e diz grep para tratar o padrão como uma string fixa, não uma expressão regular.
Como alternativa, pode-se escapar dos períodos para que eles correspondam apenas aos períodos (dica do chapéu: Nick ):
$ echo "$gene" | grep '\.\.'
gene 89..1483
gene complement(1987..2763)
Ou então podemos forçar grep a tratar os períodos como períodos literais colocando-os dentro de classes de caracteres (dica do chapéu: dave_thompson ):
$ echo "$gene" | grep '[.][.]'
gene 89..1483
gene complement(1987..2763)
Se você não precisa de expressões regulares, use -F porque isso torna o processamento grep muito mais rápido.