Como converter uma coluna de hex a dec em gawk, strtonum em gawk dá resultados errados

1

Estou tentando fazer o script de um banco de dados a partir de um fluxo de rede. O fluxo de rede depois de ser strongmente sed'd cai um arquivo de três colunas que se parece com algo chamado file.db

123.123.123.123,computer name,110000103e21cc4

123.123.123.124,computer2,11000010416200f

123.123.123.1,computer3,110000106eb3f43

Eu tentei usar este comando gawk sem sucesso

gawk 'BEGIN {FS=OFS=","} {print $1,$2,strtonum("0x"$3)}' file.db

a saída acima se parece com isso

123.123.123.123,computer name,76561198025415874

123.123.123.124,computer2,76561198028824592

123.123.123.1,computer3,76561198076346171

no entanto, a saída deve ser convertida para esta

123.123.123.123,computer name,76561198025415876

123.123.123.124,computer2,76561198028824591

123.123.123.1,computer3,76561198076346179

a saída está sempre desligada por um valor menor, então eu estou supondo que alguma biblioteca no sistema não está correta ... btw este é um sistema embarcado este está em execução e eu sei que pode converter causa ive feito com bc , printf, etc etc

Como posso fazer isso funcionar

    
por Chris 28.07.2014 / 19:22

2 respostas

0

Internamente gawk armazena o valor convertido em um ponto flutuante de precisão dupla, portanto, a pequena discrepância é apenas um erro de arredondamento hereditário de qualquer valor de ponto flutuante. Para obter um resultado preciso, gawk precisa eliminar a manipulação de números para outros comandos que suportam números de precisão arbitrários, como bc .

No entanto, com a atual sintaxe gawk , é impossível fazer uma análise complexa da linha de comando do shell no gawk, portanto, seria necessário primeiro um auxiliar de script de shell. Vamos citar bc.sh :

#!/bin/bash
echo -e "ibase=16\n$1" | bc -q

Este script alimenta ibase=16 e o primeiro argumento (número hexadecimal) em bc , de modo que bc produz o número decimal correspondente. Então gawk seria chamado assim:

gawk 'BEGIN {FS=OFS=","} { "./bc.sh " toupper($3) | getline b; print $1,$2,b}' file.db

Isso diz a gawk para chamar o script de shell com $ 3 ( bc não suporta valor hexadecimal), armazenar o resultado na variável b e imprimir todos os argumentos de uma só vez.

Esteja ciente de que ./bc.sh deve ter algum espaço anexado dentro de aspas duplas, caso contrário, ele tentará executar um arquivo inexistente como ./bc.sh110000103E21CC4 .

    
por 28.07.2014 / 22:36
0

Eu olho para trás e a maneira que acabei fazendo isso é

fazendo um script bash como o convert12345678.sh

#!/opt/bin/bash
(echo -e "ibase=16\nobase=0A" ; echo $1 | tr 'a-z' 'A-Z') | bc | tr "\n" " " | sed 's/\ //g'

e, em seguida, no gawk para o que eu precisava dizer como no op (eu modifiquei strongmente esse programa desde) foi algo assim, e eu canalizei este programa, mas vou demonstrar a partir de um arquivo

gawk -F, '{printf("%s,%s,",$1,$2)};{system("/files/convert12345678 "$3)};{printf("\n")}' file.db

eu fiz desta forma removendo a nova linha no script bash porque honestamente eu o movi depois, a colocação de execução de script que é, então dessa forma eu não teria a nova linha inserida na saída imediatamente após a conversão a menos que eu quisesse para com printf

    
por 16.01.2016 / 18:13