Làm thế nào để chuyển đổi một cột hex thành dec in gawk, strtonum trong gawk cho kết quả sai


1

Tôi đang cố gắng để kịch bản một cơ sở dữ liệu từ một luồng mạng. Luồng mạng sau khi bị giảm mạnh sẽ làm rơi một tệp ba cột trông giống như tệp này được gọi là file.db

123.123.123.123, tên máy tính, 110000103e21cc4

123.123.123.124, máy tính2,11000010416200f

123.123.123.1, máy tính3,110000106eb3f43

tôi đã cố gắng sử dụng lệnh gawk này nhưng không có kết quả

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

đầu ra từ phía trên trông như thế này

123.123.123.123, tên máy tính, 76561198025415874

123.123.123.124, máy tính2,76561198028824592

123.123.123.1, máy tính3,76561198076346171

tuy nhiên đầu ra nên chuyển đổi sang cái này

123.123.123.123, tên máy tính, 76561198025415876

123.123.123.124, máy tính2,76561198028824591

123.123.123.1, máy tính3,76561198076346179

đầu ra luôn bị tắt bởi một lượng nhỏ, vì vậy tôi giả sử một số thư viện trên hệ thống không chính xác ... btw đây là một hệ thống nhúng đang chạy và tôi biết nó có thể chuyển đổi vì tôi đã thực hiện nó với bc, printf, Vân vân

Làm thế nào tôi có thể làm cho công việc này

Câu trả lời:


0

Nội bộ gawk lưu trữ giá trị được chuyển đổi thành một dấu phẩy động chính xác kép, do đó, sự khác biệt nhỏ chỉ là lỗi thừa kế tròn cho bất kỳ giá trị dấu phẩy động nào. Để có kết quả chính xác, gawk cần xử lý số ngoài nguồn cho các lệnh khác hỗ trợ các số chính xác tùy ý, chẳng hạn như bc.

Tuy nhiên, với hiện tại gawk cú pháp không thể thực hiện phân tích cú pháp dòng lệnh shell phức tạp trong gawk, do đó trước tiên nó cần một trình trợ giúp kịch bản lệnh shell. Hãy đặt tên cho nó bc.sh:

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

Kịch bản này ăn ibase=16 và đối số đầu tiên (số hex) thành bc, vậy đó bc đầu ra số thập phân tương ứng. Sau đó gawk sẽ được gọi theo cách này:

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

Điều này nói gawk để gọi tập lệnh shell với $ 3 ( bc không hỗ trợ giá trị hex chữ thường), lưu kết quả vào b biến và in tất cả các đối số trong một lần.

Coi chừng ./bc.sh phải có một số khoảng trắng được thêm vào bên trong trích dẫn kép, nếu không nó sẽ cố thực thi tệp không tồn tại như ./bc.sh110000103E21CC4.


điều này hoạt động nếu tôi thực hiện mã trước đó và cắt bớt cột ba và sau đó sử dụng dán, nhưng tôi thích cái gì đó có thể được thực hiện với awk. Điều này là do nếu có bất cứ điều gì phá vỡ sự hình thành của tệp db, tức là một dòng bổ sung hoặc nhiều hơn không được phân tích cú pháp với sed, nó sẽ gây ra vấn đề lớn với việc dán. hãy nhớ rằng đây là đầu vào phát trực tiếp từ ngrep và trong khi tập lệnh sed không được đăng đã được mài giũa khá tốt, một số thứ có thể lướt qua ... đầu ra của phần này của tập lệnh được kết hợp với một cơ sở dữ liệu lớn hơn và tính toàn vẹn là phải
Chris

@Chris Sử dụng awk là có thể, nhưng với giới hạn về giá trị số, một số loại bộ lọc bên ngoài phải được sử dụng. Tuy nhiên awk có thể gọi các chương trình bên ngoài, cách hacky để giải quyết vấn đề này khiến tôi tin rằng viết một kịch bản shell (sử dụng cutbc ) phù hợp hơn cho nhiệm vụ này hơn awk một mình. Dù sao, tôi sẽ sửa đổi giải pháp để phù hợp với yêu cầu của bạn, tùy bạn quyết định cách thực hiện.
Abel Cheung

0

Tôi nhìn lại điều này và cách mà tôi đã kết thúc việc này là

tạo một tập lệnh bash giống như được gọi là convert12345678.sh

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

và sau đó trong gawk cho bất cứ điều gì tôi cần nói như trong op (tôi đã sửa đổi rất nhiều chương trình đó kể từ đó) là một cái gì đó như thế này, và tôi đã dẫn chương trình này nhưng tôi sẽ chứng minh từ một tập tin

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

Tôi đã làm theo cách này để loại bỏ dòng mới trong tập lệnh bash bởi vì thật lòng tôi đã di chuyển nó xung quanh sau đó, vị trí thực thi tập lệnh, vì vậy theo cách này tôi sẽ không có dòng mới được đưa vào đầu ra ngay sau khi chuyển đổi trừ khi tôi muốn in

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.