awk obtém grupos de linhas e executa operações em colunas

2

Eu tenho um arquivo com a seguinte estrutura:

Ti    1.9699858320     2.0810775390    4.162155079     5.20200
O     1.6428341970     2.0810775390    4.162155079    -2.14259
O     1.6428341970     2.0810775390    4.162155079    -2.14259
Pb    4.1621550790     4.1621550790    4.192557641     3.39279
O     3.7662066970     4.1621550790    4.192557641    -4.29652
Ti    6.1302323500     6.2584338990    4.192557641     5.23841
O     5.8163744340     6.2584338990    4.192557641    -2.13267
O     5.8163744340     6.2584338990    4.192557641    -2.13267
Pb    8.3547127200     8.3547127200    4.196295567     3.40984
O     7.9266344100     8.3547127200    4.196295567    -4.36260
Ti    10.318243871     10.452860504    4.196295567     5.26652
O     9.9935741680     10.452860504    4.196295567    -2.13625
O     9.9935741680     10.452860504    4.196295567    -2.13625
Pb    12.551008287     12.551008287    4.193631562     3.43289
O     12.112224767     12.551008287    4.193631562    -4.38552

Eu preciso para as seguintes operações:

  1. subtrair coluna 3 da coluna 2)
  2. Multiplique os resultados de 1) com a coluna 5: isso eu faço com:

    awk '{print $0,"    ",($2-$3)*$5 > "file-out.dat"}' file-in.dat
    
  3. (esta é a parte complicada) com o resultado de 2) Preciso obter a soma de cada grupo de 5 entradas. Veja como o arquivo deve ficar após o ponto 2). Eu preciso adicionar as entradas da última coluna em grupos de 5 e escrever o resultado da seguinte forma:

Ti    1.9699858320     2.0810775390    4.162155079     5.20200      -0.577899    1 result_of_sum_of_first_group_of_5
O     1.6428341970     2.0810775390    4.162155079    -2.14259      0.938976    2 result_of_sum_of_second_group_of_5
O     1.6428341970     2.0810775390    4.162155079    -2.14259      0.938976    3 result_of_sum_of_third_group_of_5
Pb    4.1621550790     4.1621550790    4.192557641     3.39279      0
O     3.7662066970     4.1621550790    4.192557641    -4.29652      1.7012
Ti    6.1302323500     6.2584338990    4.192557641     5.23841      -0.671572
O     5.8163744340     6.2584338990    4.192557641    -2.13267      0.942767
O     5.8163744340     6.2584338990    4.192557641    -2.13267      0.942767
Pb    8.3547127200     8.3547127200    4.196295567     3.40984      0
O     7.9266344100     8.3547127200    4.196295567    -4.36260      1.86753
Ti    10.318243871     10.452860504    4.196295567     5.26652      -0.708961
O     9.9935741680     10.452860504    4.196295567    -2.13625      0.98115
O     9.9935741680     10.452860504    4.196295567    -2.13625      0.98115
Pb    12.551008287     12.551008287    4.193631562     3.43289      0
O     12.112224767     12.551008287    4.193631562    -4.38552      1.92429

Existe uma maneira de fazer todas essas operações em uma linha de awk?

    
por lucian 30.03.2018 / 12:44

2 respostas

1

Em duas etapas usando dois arquivos temporários:

Primeira etapa: crie o arquivo intermediário com exatamente seis colunas como tmpfile1 e o arquivo com a soma de todos os três grupos Ti como tmpfile2 :

awk '{ $6 = ($2 - $3)*$5; print }' OFS="\t" file | tee tmpfile1 |
awk '$1 == "Ti" && NR > 1 { print ++i, sum; sum = 0 } { sum += $6 } END { print ++i, sum }' OFS="\t" >tmpfile2

O primeiro comando awk simplesmente adiciona uma sexta coluna com os valores calculados de acordo com sua fórmula. O tee grava o resultado em tmpfile1 e também passa os dados para o segundo programa awk .

O segundo awk resume a nova sexta coluna. Quando ele atinge uma linha Ti , a menos que seja a primeira linha do arquivo, ele exibe a soma atual e redefine a variável sum . A soma do último conjunto de linhas é exibida no bloco END . A variável i é incrementada antes de cada saída e é o índice desejado nessa coluna. Isso cria o arquivo tmpfile2 .

tmpfile1 :

Ti  1.9699858320    2.0810775390    4.162155079 5.20200 -0.577899
O   1.6428341970    2.0810775390    4.162155079 -2.14259    0.938976
O   1.6428341970    2.0810775390    4.162155079 -2.14259    0.938976
Pb  4.1621550790    4.1621550790    4.192557641 3.39279 0
O   3.7662066970    4.1621550790    4.192557641 -4.29652    1.7012
Ti  6.1302323500    6.2584338990    4.192557641 5.23841 -0.671572
O   5.8163744340    6.2584338990    4.192557641 -2.13267    0.942767
O   5.8163744340    6.2584338990    4.192557641 -2.13267    0.942767
Pb  8.3547127200    8.3547127200    4.196295567 3.40984 0
O   7.9266344100    8.3547127200    4.196295567 -4.36260    1.86753
Ti  10.318243871    10.452860504    4.196295567 5.26652 -0.708961
O   9.9935741680    10.452860504    4.196295567 -2.13625    0.98115
O   9.9935741680    10.452860504    4.196295567 -2.13625    0.98115
Pb  12.551008287    12.551008287    4.193631562 3.43289 0
O   12.112224767    12.551008287    4.193631562 -4.38552    1.92429

tmpfile2 :

1       3.00125
2       3.08149
3       3.17763

Segundo passo: Cole os itens juntos:

paste tmpfile1 tmpfile2

Isso produz

Ti      1.9699858320    2.0810775390    4.162155079     5.20200 -0.577899       1       3.00125
O       1.6428341970    2.0810775390    4.162155079     -2.14259        0.938976        2       3.08149
O       1.6428341970    2.0810775390    4.162155079     -2.14259        0.938976        3       3.17763
Pb      4.1621550790    4.1621550790    4.192557641     3.39279 0
O       3.7662066970    4.1621550790    4.192557641     -4.29652        1.7012
Ti      6.1302323500    6.2584338990    4.192557641     5.23841 -0.671572
O       5.8163744340    6.2584338990    4.192557641     -2.13267        0.942767
O       5.8163744340    6.2584338990    4.192557641     -2.13267        0.942767
Pb      8.3547127200    8.3547127200    4.196295567     3.40984 0
O       7.9266344100    8.3547127200    4.196295567     -4.36260        1.86753
Ti      10.318243871    10.452860504    4.196295567     5.26652 -0.708961
O       9.9935741680    10.452860504    4.196295567     -2.13625        0.98115
O       9.9935741680    10.452860504    4.196295567     -2.13625        0.98115
Pb      12.551008287    12.551008287    4.193631562     3.43289 0
O       12.112224767    12.551008287    4.193631562     -4.38552        1.92429

O resultado é delimitado por tabulações.

    
por 30.03.2018 / 12:59
0

Aqui está uma abordagem awk pura:

$ awk 'BEGIN{c=0}
       {
        $6 = ($2 - $3)*$5; 
        a[NR]=$0; 
        sum+=$6
        if(NR%5==0){
            a[++c]=$0" "sum; 
            sum=0;
        } 
       }
       END{ 
        for(i in a){
            print a[i]
            }
        }' file
O 3.7662066970 4.1621550790 4.192557641 -4.29652 1.7012 3.00125
O 7.9266344100 8.3547127200 4.196295567 -4.36260 1.86753 3.0815
O 12.112224767 12.551008287 4.193631562 -4.38552 1.92429 3.17763
Pb 4.1621550790 4.1621550790 4.192557641 3.39279 0
O 3.7662066970 4.1621550790 4.192557641 -4.29652 1.7012
Ti 6.1302323500 6.2584338990 4.192557641 5.23841 -0.671572
O 5.8163744340 6.2584338990 4.192557641 -2.13267 0.942767
O 5.8163744340 6.2584338990 4.192557641 -2.13267 0.942767
Pb 8.3547127200 8.3547127200 4.196295567 3.40984 0
O 7.9266344100 8.3547127200 4.196295567 -4.36260 1.86753
Ti 10.318243871 10.452860504 4.196295567 5.26652 -0.708961
O 9.9935741680 10.452860504 4.196295567 -2.13625 0.98115
O 9.9935741680 10.452860504 4.196295567 -2.13625 0.98115
Pb 12.551008287 12.551008287 4.193631562 3.43289 0
O 12.112224767 12.551008287 4.193631562 -4.38552 1.92429

Observe que isso removerá as guias se, como parece ser o caso, o arquivo de entrada estiver separado por tabulação. Se isso é um problema, você poderia colocá-los de volta com sed :

$ awk '...' | sed 's/ /\t/g'
O   3.7662066970    4.1621550790    4.192557641 -4.29652    1.7012  3.00125
O   7.9266344100    8.3547127200    4.196295567 -4.36260    1.86753 3.0815
O   12.112224767    12.551008287    4.193631562 -4.38552    1.92429 3.17763
Pb  4.1621550790    4.1621550790    4.192557641 3.39279 0
O   3.7662066970    4.1621550790    4.192557641 -4.29652    1.7012
Ti  6.1302323500    6.2584338990    4.192557641 5.23841 -0.671572
O   5.8163744340    6.2584338990    4.192557641 -2.13267    0.942767
O   5.8163744340    6.2584338990    4.192557641 -2.13267    0.942767
Pb  8.3547127200    8.3547127200    4.196295567 3.40984 0
O   7.9266344100    8.3547127200    4.196295567 -4.36260    1.86753
Ti  10.318243871    10.452860504    4.196295567 5.26652 -0.708961
O   9.9935741680    10.452860504    4.196295567 -2.13625    0.98115
O   9.9935741680    10.452860504    4.196295567 -2.13625    0.98115
Pb  12.551008287    12.551008287    4.193631562 3.43289 0
O   12.112224767    12.551008287    4.193631562 -4.38552    1.92429
    
por 30.03.2018 / 13:37