2

我有一个以下格式的文本文件。

1   0x5212cb03ca115ac0  0x3665fb5f1ac1
2   0x5212cb03ca115cc0  0x3665fb5f1ac7
3   0x5212cb03ca115ea0  0x3665fb5f1acd
4   0x5212cb03ca1160c0  0x3665fb5f1ad3
5   0x5212cb03ca1162a0  0x3665fb5f1ad9
6   0x5212cb03ca1164c0  0x3665fb5f1ade
7   0x5212cb03ca1166a0  0x3665fb5f1ae4
8   0x5212cb03ca1168a0  0x3665fb5f1aea
9   0x5212cb03ca116aa0  0x3665fb5f1af0
10  0x5212cb03ca116ca0  0x3665fb5f1af6

命令:

awk  '{print $1 "  "strtonum($2)-0x5212cb03ca115ac0 "  "strtonum($3)-0x3665fb5f1ac1 }' output.txt

我得到的输出如下。

1   0     0
2   1024  6
3   2048  12
4   2048  18
5   2048  24
6   3072  29
7   4096  35
8   4096  41
9   4096  47
10  5120  53

如果您看到第 2 列中的值有一些重复的值。(2048 和 4096)。这是由于使用 strtonum 时精度损失引起的

有人可以提出一些方法来达到同样的效果,但避免这种精度损失。

4

3 回答 3

5

值得注意的是,从 4.1.0 版开始,如果您提供 --bignum 命令行标志(并且如果 gawk 是使用 bignum 支持编译的),gawk 支持 bignums。不幸的是,debian/ubuntu 打包者还没有赶上新版本(它是在 5 月发布的)。

这是我在一个合理库存的 ubuntu 系统上安装 gawk-4.1.0 所做的:

# Download the source.
$ curl http://ftp.gnu.org/gnu/gawk/gawk-4.1.0.tar.gz > gawk-4.1.0.tar.gz
# Get the needed header files
$ sudo apt-get install libgmp-dev libmpfr-dev
# Unpack the gawk distribution
$ tar xf gawk-4.1.0.tar.gz
# Configure and compile it
$ ./configure
$ make
# Install it (as /usr/local/bin/gawk)
$ sudo make install

# Try it out
$ gawk --bignum '{printf "%2d %8d %8d\n",
                 $1, strtonum($2)-0x5212cb03ca115ac0,
                 strtonum($3)-0x3665fb5f1ac1 }' test.dat 
 1        0        0
 2      512        6
 3     1344       12
 4     1536       18
 5     2016       24
 6     2560       29
 7     3040       35
 8     3552       41
 9     4064       47
10     4576       53

(实际上,这有点误导。我已经安装了 gawk 4.1,但我假装我是新做的。另外,现在我想起来了,我使用的是 .xz 文件,而不是 .gz 文件,但是我确定它们都解压缩到相同的东西。.xz版本是大小的一半。)

于 2013-08-27T04:22:31.123 回答
2

也许这可以完成工作:

awk  '{print $1 "  "strtonum("0x"substr($2,11))-0xca115ac0 "  "strtonum($3)-0x3665fb5f1ac1 }' input

和 Perl 版本:

perl -lane '{print join(" ", $F[0], hex($F[1])-0x5212cb03ca115ac0, hex($F[2]) - 0x3665fb5f1ac1)}' input
于 2013-08-27T04:04:39.677 回答
1

你可以使用bc. 这可能不是您所需要的,但我相信您可以通过 tweek 获得所需的结果......

$ cat bc_output.txt
obase=10
ibase=16
5212CB03CA115AC0 - 5212CB03CA115AC0 ; 3665FB5F1AC1 - 3665FB5F1AC1
5212CB03CA115CC0 - 5212CB03CA115AC0 ; 3665FB5F1AC7 - 3665FB5F1AC1
5212CB03CA115EA0 - 5212CB03CA115AC0 ; 3665FB5F1ACD - 3665FB5F1AC1
5212CB03CA1160C0 - 5212CB03CA115AC0 ; 3665FB5F1AD3 - 3665FB5F1AC1
5212CB03CA1162A0 - 5212CB03CA115AC0 ; 3665FB5F1AD9 - 3665FB5F1AC1
5212CB03CA1164C0 - 5212CB03CA115AC0 ; 3665FB5F1ADE - 3665FB5F1AC1
5212CB03CA1166A0 - 5212CB03CA115AC0 ; 3665FB5F1AE4 - 3665FB5F1AC1
5212CB03CA1168A0 - 5212CB03CA115AC0 ; 3665FB5F1AEA - 3665FB5F1AC1
5212CB03CA116AA0 - 5212CB03CA115AC0 ; 3665FB5F1AF0 - 3665FB5F1AC1
5212CB03CA116CA0 - 5212CB03CA115AC0 ; 3665FB5F1AF6 - 3665FB5F1AC1
quit

$ bc -l bc_output.txt
bc 1.06
Copyright 1991-1994, 1997, 1998, 2000 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
0
0
512
6
992
12
1536
18
2016
24
2560
29
3040
35
3552
41
4064
47
4576
53
于 2013-08-27T04:09:16.107 回答