copiar varias líneas de un archivo a otro

copiar varias líneas de un archivo a otro

Me gustaría usar grep para copiar de un archivo a otro todas las líneas que están entre líneas /protein_id=hasta el final de la secuencia de proteínas que se muestra. Por ejemplo, a partir de esta 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

Me gustaría este resultado:

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

Tenga en cuenta que la entrada podría variar en el sentido de que la línea que comienza con regulatorypodría reemplazarse por otra cosa. Lo que no cambia es que la secuencia se da en letras mayúsculas y termina con ". ¿Es posible con grep?

Respuesta1

pcregrepes una utilidad grep que utiliza expresiones regulares compatibles con perl 5. Las expresiones regulares estilo Perl tienen muchas características útiles que las POSIX estándar no tienen. Esto es básicamente lo mismo que grep pero con una sintaxis de expresiones regulares diferente.

sudo apt-get install pcregrep  
pcregrep -M .*'/protein_id=.*(\n|.)*\"' path/to/input-file 

/protein_ides el término de búsqueda inicial y "es el término de búsqueda final.

A continuación se muestra un ejemplo generalizado de un comando para realizar una búsqueda multilínea para todas las líneas que se encuentran entre un término de búsqueda inicial y un término de búsqueda final:

pcregrep -M .*'START-SEARCH-TERM.*(\n|.)*END-SEARCH-TERM' path/to/SOURCE-FILE >> path/to/DESTINATION-FILE  

dónde:

  • SOURCE-FILE es el archivo que contiene sus datos
  • DESTINATION-FILE es el archivo donde se copiarán los resultados.
  • START-SEARCH-TERM es el término de búsqueda inicial
  • END-SEARCH-TERM es el término de búsqueda final
  • -M, --multilinePermita que los patrones coincidan con más de una línea.

Respuesta2

No, grepno se pueden hacer coincidencias en varias líneas. Podrías hacerlo pcregrepcomo lo muestra @karel, pero no puro grep. En cambio, como sabes que las secuencias de proteínas siempre estarán en MAYÚSCULAS y terminarán en ", podrías hacer coincidir eso:

  1. sed

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

    El sedpatrón /foo/,/bar/{p}significa "imprimir todas las líneas entre fooy bar. -nSuprime la salida normal, por lo que solo se imprimen las líneas solicitadas. Tenga en cuenta que es necesario utilizar el /carácter /protein_id=de escape ( \/) porque /es parte del operador de coincidencia. El segundo patrón es un poco más complejo. busca 0 o más espacios al principio de la línea ( ^\s*), luego una o más letras mayúsculas seguidas de una comilla doble ( [[:upper:]]") y luego 0 o más espacios en blanco hasta el final de la línea ( \s*$).

  2. perla

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

    La misma idea aquí, el ...operador especifica un rango y se imprimen líneas entre los dos patrones.

  3. awk

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

    Aquí, configuramos la variable asi 1la línea coincide con el primer patrón y 0si coincide con el último. Luego le decimos awkque imprima si aes 1. Dado que la printllamada anterior aestá configurada 0para el segundo patrón, esto incluirá también la línea que contiene el segundo patrón.

información relacionada