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 regulatory
podrí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
pcregrep
es 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_id
es 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, --multiline
Permita que los patrones coincidan con más de una línea.
Respuesta2
No, grep
no se pueden hacer coincidencias en varias líneas. Podrías hacerlo pcregrep
como 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:
sed
sed -n '/\/protein_id=/,/^\s*[[:upper:]]\+"\s*$/{p}' two_seq.txt
El
sed
patrón/foo/,/bar/{p}
significa "imprimir todas las líneas entrefoo
ybar
.-n
Suprime 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*$
).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.awk
awk '/\/protein_id=/{a=1}; a==1{print} /^\s*[[:upper:]]+"\s*$/{a=0}' file.flat
Aquí, configuramos la variable
a
si1
la línea coincide con el primer patrón y0
si coincide con el último. Luego le decimosawk
que imprima sia
es1
. Dado que laprint
llamada anteriora
está configurada0
para el segundo patrón, esto incluirá también la línea que contiene el segundo patrón.