Como grep para literal '..'

1

Estou analisando um arquivo usando o grep e a saída na tela contém nova linha, como aqui:

$ grep 'gene' sequence.gb
     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"

Eu posso atribuir isso a uma variável e imprimir ainda com as novas linhas:

$ gene=$(grep 'gene' sequence.gb)
echo "$gene"
     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"

mas isso não contém novas linhas reais, pois se eu usar grep novamente para as linhas que contenham '..' recebo o lote inteiro:

$ 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"

Podemos ver que esta é uma string única por não usar as aspas:

$ echo $gene
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"

Então, minha pergunta é: como posso manter a formatação de nova linha ou introduzi-la?

Obrigado

    
por Gigiux 22.05.2018 / 19:54

1 resposta

11

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.

    
por 22.05.2018 / 19:59