copie várias linhas de um arquivo para outro

2

Eu gostaria de usar o grep para copiar de um arquivo para outro todas as linhas que estão entre as linhas /protein_id= até o final da seqüência de proteínas mostrada. Por exemplo, desta entrada:

 CDS             448..1269
                 /gene="nptII"
                 /note="neomycin phosphotransferase II"
                 /codon_start=1
                 /product="kanamycin resistance protein"
                 /protein_id="AAQ05967.1"
                 /db_xref="GI:33320494"
                 /translation="MAITLSATSLPISARIRAGSPAAWVERLFGYDWAQQTIGCSDAA
                 VFRLSAQGRPVLFVKTDLSGALNELQDEAARLSWLATTGVPCAAVLDVVTEAGRDWLL
                 LGEVPGQDLLSSHLAPAEKVSIMADAMRRLHTLDPATCPFDHQAKHRIERARTRMEAG
                 LVDQDDLDEEHQGLAPAELFARLKARMPDGEDLVVTHGDACLPNIMVENGRFSGFIDC
                 GRLGVADRYQDIALATRDIAEELGGEWADRFLVLYGIAAPDSQRIAFYRLLDEFF"
  regulatory      1443..2148

Eu gostaria que esta saída:

                 /protein_id="AAQ05967.1"
                 /db_xref="GI:33320494"
                 /translation="MAITLSATSLPISARIRAGSPAAWVERLFGYDWAQQTIGCSDAA
                 VFRLSAQGRPVLFVKTDLSGALNELQDEAARLSWLATTGVPCAAVLDVVTEAGRDWLL
                 LGEVPGQDLLSSHLAPAEKVSIMADAMRRLHTLDPATCPFDHQAKHRIERARTRMEAG
                 LVDQDDLDEEHQGLAPAELFARLKARMPDGEDLVVTHGDACLPNIMVENGRFSGFIDC
                 GRLGVADRYQDIALATRDIAEELGGEWADRFLVLYGIAAPDSQRIAFYRLLDEFF"

Observe que a entrada pode variar em que a linha que inicia com regulatory possa ser substituída por outra coisa. O que é imutável é que a sequência é dada em letras maiúsculas e termina com " . É possível com o grep?

    
por Urszula Uciechowska 25.03.2015 / 12:54

1 resposta

3

Não, grep não pode corresponder em várias linhas. Você poderia fazer isso com pcregrep como mostrado por @karel, mas não grep puro. Em vez disso, uma vez que você sabe que as sequências de proteínas sempre estarão no maiúsculas e terminarão com " , você pode combinar isso:

  1. sed

    sed -n '/\/protein_id=/,/^\s*[[:upper:]]\+"\s*$/{p}' two_seq.txt
    

    O sed padrão /foo/,/bar/{p} significa "imprimir todas as linhas entre foo e bar . A -n suprime a saída normal, portanto, apenas as linhas solicitadas são impressas. Observe que / of /protein_id= precisa ser escapado ( \/ ) porque o / é parte do operador de correspondência.O segundo padrão é um pouco mais complexo, ele procura por 0 ou mais espaços no início da linha ( ^\s* ), então uma ou mais letras maiúsculas seguidas por aspas duplas ( [[:upper:]]" ) e depois 0 ou mais caracteres em branco até o final da linha ( \s*$ ).

  2. Perl

    perl -ne 'print if m#/protein_id=# ... m#[A-Z]+"\s*$#' file.flat 
    

    A mesma ideia aqui, o operador ... especifica um intervalo e as linhas entre os dois padrões são impressas.

  3. awk

    awk '/\/protein_id=/{a=1}; a==1{print} /^\s*[[:upper:]]+"\s*$/{a=0}' file.flat 
    

    Aqui, definimos a variável a to 1 se a linha corresponder ao primeiro padrão e a 0 se corresponder à última. Em seguida, informamos awk para imprimir se a for 1 . Como o print é chamado antes de a ser definido como 0 para o segundo padrão, isso incluirá a linha contendo o segundo padrão também.

por terdon 25.03.2015 / 14:05