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 gawk
als Gleitkommazahl mit doppelter Genauigkeit, sodass die kleine Abweichung nur ein Rundungsfehler ist, der bei allen Gleitkommazahlen auftritt. Um genaue Ergebnisse zu erhalten, gawk
muss 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 gawk
unmö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=16
das erste Argument (Hexadezimalzahl) in ein bc
, sodass bc
die entsprechende Dezimalzahl ausgegeben wird. Dann gawk
wü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 ( bc
kleingeschriebene Hex-Werte werden nicht unterstützt), das Ergebnis in der b
Variablen zu speichern und alle Argumente auf einmal auszudrucken.
Beachten Sie, dass ./bc.sh
in 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