Serie de números en una determinada posición en varias líneas

Serie de números en una determinada posición en varias líneas

Tengo un conjunto de datos que se parece a este:

>TRINITY_DN37_c0_g1_i1 len=333 path=[361:0-43 362:44-332] [-1, 361, 362, -2]
GCCGCCATCATGGATGCCAGCCGTGTGCAGCCCATCAAGCTTGCCAGAGTCACCAAGGTT
>TRINITY_DN37_c0_g2_i1 len=356 path=[359:0-66 360:67-355] [-1, 359, 360, -2]
ACGTGACCCCCTTTCTGTCTCAAGCCGCCATCATGGATGCCAGTCGTGTGCAGCCCATCA
>TRINITY_DN15_c1_g1_i1 len=394 path=[372:0-393] [-1, 372, -2]
GCACTTACCATGCATGGAAGGCAAATGCCATCGGAAGGTCTGCAAAGACTGTTAGGGAGT

Necesitaría reemplazar la cadena 'len=XXX', que está en la misma posición en miles de líneas, con una serie de números para etiquetar de forma única cada secuencia. Idealmente estaba pensando en algo como:

>TRINITY_DN37_c0_g1_i1 1 path=[361:0-43 362:44-332] [-1, 361, 362, -2]
GCCGCCATCATGGATGCCAGCCGTGTGCAGCCCATCAAGCTTGCCAGAGTCACCAAGGTT
>TRINITY_DN37_c0_g2_i1 2 path=[359:0-66 360:67-355] [-1, 359, 360, -2]
ACGTGACCCCCTTTCTGTCTCAAGCCGCCATCATGGATGCCAGTCGTGTGCAGCCCATCA
>TRINITY_DN15_c1_g1_i1 3 path=[372:0-393] [-1, 372, -2]
GCACTTACCATGCATGGAAGGCAAATGCCATCGGAAGGTCTGCAAAGACTGTTAGGGAGT

Estoy usando OSX.

¿Algunas ideas?

Respuesta1

$ cat ip.txt 
>TRINITY_DN37_c0_g1_i1 len=333 path=[361:0-43 362:44-332] [-1, 361, 362, -2]
GCCGCCATCATGGATGCCAGCCGTGTGCAGCCCATCAAGCTTGCCAGAGTCACCAAGGTT
>TRINITY_DN37_c0_g2_i1 len=356 path=[359:0-66 360:67-355] [-1, 359, 360, -2]
ACGTGACCCCCTTTCTGTCTCAAGCCGCCATCATGGATGCCAGTCGTGTGCAGCCCATCA
>TRINITY_DN15_c1_g1_i1 len=394 path=[372:0-393] [-1, 372, -2]
GCACTTACCATGCATGGAAGGCAAATGCCATCGGAAGGTCTGCAAAGACTGTTAGGGAGT

$ awk '/len=/{sub(/len=[0-9]+/,++c)} 1' ip.txt 
>TRINITY_DN37_c0_g1_i1 1 path=[361:0-43 362:44-332] [-1, 361, 362, -2]
GCCGCCATCATGGATGCCAGCCGTGTGCAGCCCATCAAGCTTGCCAGAGTCACCAAGGTT
>TRINITY_DN37_c0_g2_i1 2 path=[359:0-66 360:67-355] [-1, 359, 360, -2]
ACGTGACCCCCTTTCTGTCTCAAGCCGCCATCATGGATGCCAGTCGTGTGCAGCCCATCA
>TRINITY_DN15_c1_g1_i1 3 path=[372:0-393] [-1, 372, -2]
GCACTTACCATGCATGGAAGGCAAATGCCATCGGAAGGTCTGCAAAGACTGTTAGGGAGT
  • /len=/líneas que coinciden con este patrón
  • sub(/len=[0-9]+/,++c)reemplace la primera aparición del len=[0-9]+patrón de línea coincidente con un valor incrementado de c(el valor predeterminado es 0)


O conperl

perl -i -pe 's/len=\d+/++$c/e' ip.txt

la -iopción es para edición in situ

Respuesta2

Otra solución diferente a la de Sundeep que utiliza otro mecanismo awk.

awk '
$2 ~ /len=/ { $2=++ctr}
{ print }
' < file     

$2 ~ /len=/coincide solo con las líneas donde el segundo campo contiene len=y en esas líneas, el segundo campo se reemplaza por un contador.

Luego, se imprimen todas las líneas, independientemente de si coinciden o no con la primera regla.

Si desea iniciar el contador desde un valor inicial determinado (si su entrada está separada en varios archivos, por ejemplo), puede hacer:

awk '
BEGIN { ctr=12345 }
$2 ~ /len=/ { $2=ctr++ }
{ print }
' < file

información relacionada