Concatenar Colunas se Outros Campos Corresponderem

1

Eu tenho um arquivo delimitado por tabulação com 6 campos. Se os campos $1 , $2 , $4 , $5 e $6 corresponderem, quero mesclá-los em uma única linha e concatenar o campo $3 com / entre cada valor.

input.txt

1   109860777   COSN18724706    CT  C   SORT1
1   154842199   COSM3685920 G   GGCTGCTGCTGCTGCT,GGCTGCTGCTGCTGCTGCT    KCNN3
1   154842199   COSM5827506 G   GGCTGCTGCTGCTGCT,GGCTGCTGCTGCTGCTGCT    KCNN3
1   1684347 COSM1320773 C   CCCT    NADK
1   1684347 COSM1320774 C   CCCT    NADK
1   1684347 COSM5827581 C   CCCT    NADK
1   248801602   COSM246232  T   TCA OR2T35

output.txt

1   109860777   COSN18724706    CT  C   SORT1
1   154842199   COSM3685920/COSM5827506 G   GGCTGCTGCTGCTGCT,GGCTGCTGCTGCTGCTGCT    KCNN3
1   1684347 COSM1320773/COSM1320774/COSM5827581 C   CCCT    NADK
1   248801602   COSM246232  T   TCA OR2T35

Eu tentei usar o awk, mas eu poderia usar o push na direção certa.

    
por steveho 13.06.2017 / 03:24

3 respostas

1
Solução

awk :

awk '{ k=$1 FS $2 FS $4 FS $5 FS $6;  a[k]=(k in a)? a[k]"/"$3 : $3 }
     END{ for(i in a) { 
              split(i,b,FS); b[3]=a[i]"\t"b[3]; r=""; 
              for(j=1;j<=NF;j++) { 
                  r=(r!="")? r"\t"b[j] : b[j] 
              } 
              print r 
        } 
     }' input

A saída:

1   1684347 COSM1320773/COSM1320774/COSM5827581 C   CCCT    NADK    
1   109860777   COSN18724706    CT  C   SORT1   
1   154842199   COSM3685920/COSM5827506 G   GGCTGCTGCTGCTGCT,GGCTGCTGCTGCTGCTGCT    KCNN3   
1   248801602   COSM246232  T   TCA OR2T35

Detalhes :

  • k=$1 FS $2 FS $4 FS $5 FS $6 - chave de matriz complexa

  • a[k]=(k in a)? a[k]"/"$3 : $3 - concatenando o valor do terceiro campo para registros com campos combinados / agrupados

  • split(i,b,FS) - chave de matriz dividida por separador

  • b[3]=a[i]"\t"b[3] - inserindo o valor resultante (3º campo) na respectiva posição

por 13.06.2017 / 08:22
1

Usando GNU sed para facilitar a aparência do código, podemos fazer da seguinte maneira:

sed -Ee '
   $!N
   s|^(\S+\t\S+\t)(\S+)(\t\S+\t\S+\t\S+)(\n)(\S+)$|/|
   /^\n/!P;D
' yourfile

Resultados

1       109860777       COSN18724706    CT      C       SORT1
1       154842199       COSM3685920/COSM5827506 G       GGCTGCTGCTGCTGCT,GGCTGCTGCTGCTGCTGCT    KCNN3
1       1684347 COSM1320773/COSM1320774/COSM5827581     C       CCCT    NADK
1       248801602       COSM246232      T       TCA     OR2T35

Trabalhando

  • Invoque GNU sed com a opção -E para ativar as REs estendidas.
  • Carregue a próxima linha no padrão, a menos que seja a eof.
  • Assumimos que não existiam TABs iniciais / finais nem múltiplos TABs entre campos.
  • Club $ 1 $ 2 em \ 1, $ 3 em \ 2, $ 4, $ 5, $ 6 em \ 3.
  • Em seguida, tente fazer o sub como mostrado. Se bem sucedidos, então nós teríamos movido os $ 3 da próxima linha para os $ 3 da corrente, separados por uma barra E uma nova linha no BOL.
  • Em seguida, imprimimos a linha atual na falha do sub, OTW, refazemos o código sed com o que temos no espaço padrão.
por 13.06.2017 / 08:36
0

Aqui está uma maneira de fazer isso usando o Python:

Código:

from collections import OrderedDict
data = OrderedDict()
with open('file1', 'rU') as f:
    for line in f.readlines():
        line = line.split('\t')
        key = tuple(line[:2] + line[3:])
        data.setdefault(key, []).append(line[2])

with open('file2', 'w') as f:
    for k, v in data.items():
        f.write('\t'.join([k[0], k[1], '/'.join(v)] + list(k[2:])))

Resultados:

1   109860777   COSN18724706    CT  C   SORT1
1   154842199   COSM3685920/COSM5827506 G   GGCTGCTGCTGCTGCT,GGCTGCTGCTGCTGCTGCT    KCNN3
1   1684347 COSM1320773/COSM1320774/COSM5827581 C   CCCT    NADK
1   248801602   COSM246232  T   TCA OR2T35
    
por 13.06.2017 / 04:14