Como converter uma coluna hexadecimal em dec no gawk, strtonum no gawk fornece resultados errados

Como converter uma coluna hexadecimal em dec no gawk, strtonum no gawk fornece resultados errados

Estou tentando criar um script de banco de dados a partir de um fluxo de rede. O fluxo de rede após ser fortemente sed descarta um arquivo de três colunas parecido com este chamado file.db

123.123.123.123, nome do computador, 110000103e21cc4

123.123.123.124,computador2,11000010416200f

123.123.123.1,computador3,110000106eb3f43

tentei usar esse comando gawk sem sucesso

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

a saída acima é assim

123.123.123.123, nome do computador, 76561198025415874

123.123.123.124,computador2,76561198028824592

123.123.123.1,computador3,76561198076346171

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

123.123.123.123, nome do computador, 76561198025415876

123.123.123.124,computador2,76561198028824591

123.123.123.1,computador3,76561198076346179

a saída está sempre errada em uma pequena quantidade, então estou assumindo que alguma biblioteca no sistema não está correta ... aliás, este é um sistema embarcado em execução e eu sei que ele pode ser convertido porque eu fiz isso com bc, printf, etc etc

Como posso fazer isso funcionar

Responder1

Armazena internamente gawko valor convertido em um ponto flutuante de precisão dupla, portanto, a pequena discrepância é apenas um erro de arredondamento herdado de qualquer valor de ponto flutuante. Para obter resultados precisos, gawké necessário terceirizar o tratamento de números para outros comandos que suportam números de precisão arbitrários, como bc.

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

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

Este script alimenta ibase=16o primeiro argumento (número hexadecimal) em bc, de modo que bcgera o número decimal correspondente. Então gawkseria chamado desta forma:

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

Isso diz gawkpara chamar o script de shell com $3 maiúsculo ( bcnão suporta valor hexadecimal minúsculo), armazenar o resultado na bvariável e imprimir todos os argumentos de uma só vez.

Cuidado, ./bc.shdeve haver algum espaço anexado entre aspas duplas, caso contrário, ele tentará executar um arquivo inexistente, como ./bc.sh110000103E21CC4.

Responder2

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

criando um script bash como o chamado 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 então fiquei boquiaberto com o que eu precisava dizer, como na operação (modifiquei fortemente esse programa desde então) era algo assim, e 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 isso dessa maneira, removendo a nova linha no script bash porque, honestamente, eu a mudei depois, o posicionamento de execução do script, então, dessa forma, eu não teria a nova linha interposta na saída imediatamente após a conversão, a menos que eu quisesse com imprimir

informação relacionada