Estoy intentando crear un script en una base de datos desde una secuencia de red. La transmisión de red después de ser fuertemente sed arroja un archivo de tres columnas que se parece a este llamado file.db
123.123.123.123, nombre de computadora, 110000103e21cc4
123.123.123.124,computadora2,11000010416200f
123.123.123.1, computadora3,110000106eb3f43
Intenté usar este comando gawk sin éxito
gawk 'BEGIN {FS=OFS=","} {print $1,$2,strtonum("0x"$3)}' file.db
el resultado de lo anterior se ve así
123.123.123.123, nombre de computadora, 76561198025415874
123.123.123.124,computadora2,76561198028824592
123.123.123.1,computadora3,76561198076346171
sin embargo, la salida debería convertirse a esto
123.123.123.123, nombre de computadora, 76561198025415876
123.123.123.124,computadora2,76561198028824591
123.123.123.1,computadora3,76561198076346179
la salida siempre está desviada en una cantidad menor, por lo que supongo que alguna biblioteca en el sistema no es correcta... Por cierto, este es un sistema integrado que se está ejecutando y sé que puede convertir porque lo he hecho con bc, printf, etcétera etcétera
¿Cómo puedo hacer que esto funcione?
Respuesta1
Almacena internamente gawk
el valor convertido en un punto flotante de doble precisión, por lo que la pequeña discrepancia es simplemente un error de redondeo heredado de cualquier valor de punto flotante. Para obtener resultados precisos, gawk
es necesario subcontratar el manejo de números a otros comandos que admitan números de precisión arbitraria, como bc
.
Sin embargo, con la sintaxis actual gawk
es imposible realizar un análisis complejo de la línea de comandos del shell dentro de gawk, por lo que primero necesitaría un asistente de script del shell. Pongámosle un nombre bc.sh
:
#!/bin/bash
echo -e "ibase=16\n$1" | bc -q
Este script introduce ibase=16
el primer argumento (número hexadecimal) en bc
, de modo que bc
genera el número decimal correspondiente. Entonces gawk
se llamaría de esta manera:
gawk 'BEGIN {FS=OFS=","} { "./bc.sh " toupper($3) | getline b; print $1,$2,b}' file.db
Esto le indica gawk
que llame al script de shell con $3 en mayúsculas ( bc
no admite valores hexadecimales en minúsculas), almacene el resultado en b
una variable e imprima todos los argumentos de una sola vez.
Tenga en cuenta que ./bc.sh
debe tener algo de espacio añadido entre comillas dobles; de lo contrario, intentará ejecutar un archivo inexistente como ./bc.sh110000103E21CC4
.
Respuesta2
Miro hacia atrás en esto y la forma en que terminé haciendo esto es
hacer un script bash como el llamado convert12345678.sh
#!/opt/bin/bash
(echo -e "ibase=16\nobase=0A" ; echo $1 | tr 'a-z' 'A-Z') | bc | tr "\n" " " | sed 's/\ //g'
y luego, mirando boquiabierto por lo que necesitaba, dije como en la operación (he modificado mucho ese programa desde entonces) era algo como esto, y transmití este programa, pero lo demostraré desde un archivo.
gawk -F, '{printf("%s,%s,",$1,$2)};{system("/files/convert12345678 "$3)};{printf("\n")}' file.db
Lo hice de esta manera eliminando la nueva línea en el script bash porque, honestamente, la moví después, es decir, la ubicación de ejecución del script, de esta manera no tendría la nueva línea intercalada en la salida inmediatamente después de la conversión a menos que lo quisiera con imprimirf