Как преобразовать столбец hex в dec в gawk, strtonum в gawk дает ошибочные результаты

Как преобразовать столбец hex в dec в gawk, strtonum в gawk дает ошибочные результаты

Я пытаюсь написать скрипт базы данных из сетевого потока. Сетевой поток после интенсивного sed'а выдает файл с тремя столбцами, который выглядит примерно так, называется file.db

123.123.123.123,имя компьютера,110000103e21cc4

123.123.123.124,компьютер2,11000010416200f

123.123.123.1,компьютер3,110000106eb3f43

Я пытался использовать эту команду gawk, но безуспешно.

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

вывод из вышесказанного выглядит так

123.123.123.123,имя компьютера,76561198025415874

123.123.123.124,компьютер2,76561198028824592

123.123.123.1,компьютер3,76561198076346171

однако вывод должен преобразоваться в это

123.123.123.123,имя компьютера,76561198025415876

123.123.123.124,компьютер2,76561198028824591

123.123.123.1,компьютер3,76561198076346179

вывод всегда немного отличается, поэтому я предполагаю, что какая-то библиотека в системе некорректна... Кстати, это встроенная система, на которой она работает, и я знаю, что она может преобразовывать, потому что я делал это с помощью bc, printf и т. д. и т. п.

Как мне это сделать?

решение1

Внутри себя gawkсохраняет преобразованное значение в число с плавающей точкой двойной точности, поэтому небольшое расхождение — это просто ошибка округления, присущая любому значению с плавающей точкой. Чтобы получить точный результат, gawkнеобходимо передать обработку чисел другим командам, которые поддерживают числа произвольной точности, например bc.

Однако с текущим gawkсинтаксисом невозможно выполнить сложный разбор командной строки оболочки в gawk, поэтому для начала понадобится помощник скрипта оболочки. Давайте назовем его bc.sh:

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

Этот скрипт подает ibase=16первый аргумент (шестнадцатеричное число) в bc, так что bcвыводится соответствующее десятичное число. Тогда gawkон будет вызываться так:

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

Это указывает gawkна необходимость вызова скрипта оболочки с заглавными буквами $3 ( bcне поддерживает шестнадцатеричные значения в нижнем регистре), сохранения результата в bпеременной и вывода всех аргументов за один раз.

Обратите внимание, что ./bc.shвнутри двойных кавычек необходимо добавить пробел, в противном случае будет предпринята попытка выполнить несуществующий файл, например ./bc.sh110000103E21CC4.

решение2

Оглядываясь назад, я понимаю, что в итоге я пришел к такому выводу:

создание bash-скрипта, например, convert12345678.sh

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

и затем в gawk для всего, что мне было нужно, скажем, в op (я сильно изменил эту программу с тех пор) было что-то вроде этого, и я передал эту программу, но я продемонстрирую это из файла

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

Я сделал это таким образом, удалив новую строку в скрипте bash, потому что, честно говоря, я переместил ее позже, то есть место выполнения скрипта, так что таким образом я не буду вставлять новую строку в вывод сразу после преобразования, если только я не захочу этого с помощью printf.

Связанный контент