So konvertieren Sie eine Spalte von Hex in Dec in Gawk, Strtonum in Gawk liefert fehlerhafte Ergebnisse

So konvertieren Sie eine Spalte von Hex in Dec in Gawk, Strtonum in Gawk liefert fehlerhafte Ergebnisse

Ich versuche, eine Datenbank aus einem Netzwerkstream zu skripten. Der Netzwerkstream legt nach starker SED-Prüfung eine dreispaltige Datei ab, die ungefähr so ​​aussieht und file.db heißt

123.123.123.123,Computername,110000103e21cc4

123.123.123.124,computer2,11000010416200f

123.123.123.1,computer3,110000106eb3f43

ich habe versucht, diesen Gawk-Befehl zu verwenden, ohne Erfolg

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

die Ausgabe von oben sieht so aus

123.123.123.123,Computername,76561198025415874

123.123.123.124,computer2,76561198028824592

123.123.123.1,computer3,76561198076346171

Die Ausgabe sollte jedoch folgendermaßen konvertiert werden

123.123.123.123,Computername,76561198025415876

123.123.123.124,computer2,76561198028824591

123.123.123.1,computer3,76561198076346179

die Ausgabe weicht immer geringfügig ab, daher gehe ich davon aus, dass eine Bibliothek auf dem System nicht korrekt ist. Übrigens läuft dies auf einem eingebetteten System und ich weiß, dass es konvertieren kann, weil ich es mit BC, Printf usw. usw. gemacht habe.

Wie kann ich das zum Laufen bringen?

Antwort1

Speichert den konvertierten Wert intern gawkals Gleitkommazahl mit doppelter Genauigkeit, sodass die kleine Abweichung nur ein Rundungsfehler ist, der bei allen Gleitkommazahlen auftritt. Um genaue Ergebnisse zu erhalten, gawkmuss die Zahlenverarbeitung an andere Befehle ausgelagert werden, die Zahlen mit beliebiger Genauigkeit unterstützen, wie z . B. bc.

Mit der aktuellen Syntax ist es jedoch gawkunmöglich, komplexe Shell-Befehlszeilenanalysen innerhalb von gawk durchzuführen, daher wäre zunächst ein Shell-Skript-Helfer erforderlich. Nennen wir ihn bc.sh:

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

Dieses Skript speist ibase=16das erste Argument (Hexadezimalzahl) in ein bc, sodass bcdie entsprechende Dezimalzahl ausgegeben wird. Dann gawkwürde es folgendermaßen aufgerufen:

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

Dies weist an gawk, das Shell-Skript mit $3 in Großbuchstaben aufzurufen ( bckleingeschriebene Hex-Werte werden nicht unterstützt), das Ergebnis in der bVariablen zu speichern und alle Argumente auf einmal auszudrucken.

Beachten Sie, dass ./bc.shin den Anführungszeichen ein Leerzeichen angehängt werden muss, da sonst versucht wird, eine nicht vorhandene Datei wie auszuführen ./bc.sh110000103E21CC4.

Antwort2

Wenn ich zurückblicke, ist die Art und Weise, wie ich es letztendlich gemacht habe, folgende

Erstellen eines Bash-Skripts wie beispielsweise convert12345678.sh

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

und dann in gawk für alles, was ich sagen musste, wie im OP (ich habe dieses Programm seitdem stark modifiziert) war so etwas wie das hier, und ich habe dieses Programm weitergeleitet, aber ich werde es anhand einer Datei demonstrieren

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

ich habe es so gemacht, indem ich die neue Zeile im Bash-Skript entfernt habe, weil ich sie ehrlich gesagt danach verschoben habe, also an der Stelle, an der das Skript ausgeführt wurde. Auf diese Weise würde ich die neue Zeile nicht sofort nach der Konvertierung in die Ausgabe einfügen, es sei denn, ich wollte das mit printf

verwandte Informationen