Uso do AWK para divisão inline simulatenosa e valor absoluto

1

Eu tenho um arquivo de dados desse formato (a linha superior é para referência):

    E          T               N         D                 S             s                 R          k
   0.45847  300.0000      9.99979156  0.44254427E+02  0.49221658E-04  0.98763353E+19  0.73239256E-09  0.24892539E+15
   0.45947  300.0000      9.97603847  0.51763106E+02 -0.24189016E-04  0.97909193E+19 -0.24467623E-08  0.23855274E+15

Agora preciso gerar um arquivo no mesmo formato de coluna que contém:

N         (k/(s/300.0000))         Abs(S)/E         exp(Abs(S)/E)

Em suma, primeiro preciso dividir as duas colunas e pegar o valor absoluto da coluna (5) e novamente executar a exponenciação.

Estou usando o código:

while read -a line; do echo -e " ${line[2]}\t" 'awk "BEGIN {print ${line[7]}/${line[5]}/300}"' ; done < filename

Mas isso só me leva à segunda coluna. CI precisa ter o valor absoluto como nas próximas duas colunas?

Eu vim até:

 while read -a line; do echo -e ${line[4]} | awk ' { if($line[4]>=0 ) {print $line[4] } else {print $line[4]*(-1)} }'; done <

Mas não consigo combinar isso com o último código de divisão de coluna. Estou perdendo alguma sintaxe com BEGIN ou END de uso em awk ? Também o resultado sai desordenado no formato decimal. Um

P.S .: O awk é a ferramenta certa para fazer isso? Devo tentar python ou algo assim? Eu sei que não posso usar planilhas como eu vou ter mais de 2 dezenas desses arquivos.

    
por Aditya Putatunda 17.04.2018 / 23:07

2 respostas

2

Sim, awk é a ferramenta correta que você poderia fazer:

$ awk 'function abs(x) {return x<0 ? -x : x}
     NR>1{printf ("%e %e %e %e\n", $3, $NF/($6/300.0000), abs($5)/$1, exp(abs($5)/$1) );
}' infile

9.999792e+00 7.561268e-03 1.073607e-04 1.000107e+00
9.976038e+00 7.309408e-03 5.264547e-05 1.000053e+00

Você pode simular a função abs () como acima, ou usar um Operador Ternário para gerá-lo como segue sem definir uma função:

$ awk 'NR>1{ $5*=($5<0?-1:1);
    printf("%e %e %e %e\n", $3, $NF/($6/300.0000), $5/$1, exp($5/$1) )}' infile
9.999792e+00 7.561268e-03 1.073607e-04 1.000107e+00
9.976038e+00 7.309408e-03 5.264547e-05 1.000053e+00
por 18.04.2018 / 01:36
0

Se você quiser fazer isso com um script python:

#!/usr/bin/env python
##
# use: ingest.py infile1 infile2 ... infilen

import math,re,argparse

parser = argparse.ArgumentParser()
parser.add_argument('infiles', type=str, help='infile names', nargs='+')
args = parser.parse_args()

for infile in args.infiles:
    with open(infile) as in_file, open(infile+".out", "w+") as out_file:
        column_names = in_file.readline().split()
        out_file.write("N (k/(s/300.0000)) Abs(S)/E exp(Abs(S)/E)\n")
        for line in in_file.readlines():
            column_values = [float(x) for x in line.split()]
            value_dict = dict(zip(column_names,column_values))
            div = value_dict["k"]/(value_dict["s"]/300.0000)
            ABS = abs(value_dict["S"])/value_dict["E"]
            EXP = math.exp(abs(value_dict["S"])/value_dict["E"])
            out_file.write("{N} {DIV} {ABS} {EXP}\n".format(N=value_dict["N"],DIV=div,ABS=ABS, EXP=EXP))
    
por 18.04.2018 / 03:42