Encontrando diferenças entre duas linhas e adicionando-as

0

Eu quero usar awk para adicionar colunas juntas, mas apenas para um máximo de 1 e somente algumas colunas.

Veja a aparência de um arquivo de entrada com o qual estou trabalhando.

1   119 .   A   T   1000    PASS    MID=183;S=0;DOM=0.5;PO=1;GO=337;MT=1;AC=3;DP=1000;MULTIALLELIC  GT  0|0 1|0 0|0 0|0
1   119 .   A   T   1000    PASS    MID=362;S=0;DOM=0.5;PO=1;GO=562;MT=1;AC=2;DP=1000;MULTIALLELIC  GT  0|0 1|0 0|1 0|0

O que eu quero que pareça

1   119 .   A   T   1000    PASS    MID=183;S=0;DOM=0.5;PO=1;GO=337;MT=1;AC=5;DP=1000   GT  0|0 1|0 0|1 0|0

Assim, as únicas colunas que preciso adicionar são AC = # e os 0's e 1's. Os problemas que estou tendo estão lidando com linhas que têm texto neles e linhas onde ambos os valores são 1 (que eu quero resultar em 1), bem como alterar os delimitadores mid-file.

Até agora eu tenho awk 'NR%2 { split($0, a) ; next } { for (i=1; i<=NF; i++) printf " %d", a[i]+$i ; print "" } ' Infelizmente, isso transforma textos em 0s e não gera os "; s, |" e as guias.

    
por AMB 15.09.2018 / 20:25

1 resposta

0

Sua tabela é muito difícil de lidar com , mas uma maneira de fazer isso é dividir o trabalho em várias etapas. Antes de tudo, salve seus dados em um arquivo chamado data.txt e, em seguida:

  • converta a tabela em colunas com larguras fixas e substitua os espaços " " , o sinal de igual = , bem como os dois pontos ";" pelas colunas "\t" . Você pode conseguir isso combinando funções de sed e awk da seguinte maneira:

sed 's/=/\t/g; s/;/\t/g' data.txt | awk '{printf "%-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s%-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s\n", $1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$30,$31,$32,$33}'

saída:

1      119   .     A     T     1000  PASS  MID   183   S     0     DOM   0.5   PO    1     GO    337   MT    1    AC    3     DP    1000  MULTIALLELIC GT    0|0   1|0   0|0   0|0        
1      119   .     A     T     1000  PASS  MID   362   S     0     DOM   0.5   PO    1     GO    562   MT    1    AC    2     DP    1000  MULTIALLELIC GT    0|0   1|0   0|1   0|0  
  • Soma os valores em uma coluna específica, no seu caso número da coluna #21 . Você pode fazer isso canalizando a saída da etapa anterior para o seguinte comando:

awk '{ sum21+=$21} END {print sum21}')

saída:

5

- extrair a primeira linha da sua tabela usando o seguinte comando:

sed 's/=/\t/g; s/;/\t/g' data.txt| awk '{printf "%-5s  %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s%-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s\n", $1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$30,$31,$32,$33}' | head -1

saída:

1      119   .     A     T     1000  PASS  MID   183   S     0     DOM   0.5   PO    1     GO    337   MT    1    AC    3     DP    1000  MULTIALLELIC GT    0|0   1|0   0|0   0|0        

- Substitua o valor de field #21 da etapa anterior pelo sum-value da coluna # 21 e reconstruct the spaces, colons and the other symbols em sua tabela original, da seguinte maneira:

awk '{print $1,$2,$3,$4,$5,$6,$7,$8"="$9";"$10"="$11";"$12"="$13";"$14"="$15";"$16"="$17";"$18"="$19";"$20,"=",$21='$sum'";"$22"="$23";"$24,$25,$26,$27,$28,$29,$30,$31,$32,$33}'

saída:

1 119 . A T 1000 PASS MID=183;S=0;DOM=0.5;PO=1;GO=337;MT=1;AC = 5;DP=1000;MULTIALLELIC GT 0|0 1|0 0|0 0|0    

Em um bash você pode fazer isso da seguinte maneira:

#!/bin/bash
sum_col21=$(sed 's/=/\t/g; s/;/\t/g' data.txt| awk '{printf "%-5s  %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s%-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s\n", $1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$30,$31,$32,$33}' | awk '{ sum21+=$21} END {print sum21}')

first_row=$(sed 's/=/\t/g; s/;/\t/g' data.txt| awk '{printf "%-5s  %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s%-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s\n", $1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$30,$31,$32,$33}' | head -1)


echo $first_row | awk '{print $1,$2,$3,$4,$5,$6,$7,$8"="$9";"$10"="$11";"$12"="$13";"$14"="$15";"$16"="$17";"$18"="$19";"$20,"=",$21='$sum_col21'";"$22"="$23";"$24,$25,$26,$27,$28,$29,$30,$31,$32,$33}'

Esta solução será atualizada seguindo os esclarecimentos adicionais necessários no texto da pergunta.

    
por 15.09.2018 / 23:54