Série de números em uma determinada posição em várias linhas

3

Eu tenho um conjunto de dados que se parece com isso:

>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

Eu precisaria substituir a string 'len = XXX', que está na mesma posição em milhares de linhas, com uma série de números para marcar de maneira única cada sequência. Idealmente eu estava pensando em 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

Estou usando o OSX.

Alguma idéia?

    
por Luca 07.04.2017 / 11:11

2 respostas

6
$ 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=/ linhas que correspondem a esse padrão
  • sub(/len=[0-9]+/,++c) substitui a primeira ocorrência do padrão len=[0-9]+ da linha correspondente com o valor incrementado de c (o valor padrão é 0 )


Ou com perl

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

a opção -i é para edição no local

    
por 07.04.2017 / 11:19
4

Outra solução diferente da do Sundeep usando outro mecanismo do awk.

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

$2 ~ /len=/ corresponde apenas às linhas onde o segundo campo contém len= e nessas linhas, o segundo campo é substituído por um contador.

Em seguida, todas as linhas são impressas, independentemente de corresponderem à primeira regra ou não.

Se você quiser iniciar o contador a partir de um determinado valor inicial (se sua entrada for separada em vários arquivos, por exemplo), você pode fazer:

awk '
BEGIN { ctr=12345 }
$2 ~ /len=/ { $2=ctr++ }
{ print }
' < file
    
por 07.04.2017 / 11:37