我有由双浮点(8 字节)或仅浮点(4 字节)值组成的二进制文件,该文件是通过以下方式生成的:
$ python -c $'from struct import pack\nwith open("file.bin", "wb") as f: f.write(pack("<d", 0.123))'
$ xxd file.bin
00000000: b072 6891 ed7c bf3f .rh..|.?
我可以通过以下方式从 Python 打印回来:
$ python -c $'from struct import unpack\nwith open("file.bin", "rb") as f: print(unpack("<d", f.read(8)))'
(0.123,)
4字节浮点数也一样,只是改变一下<d
into <f
(提到为float.bin
稍后的)。
如何使用更清晰的方式(不使用 Python)从 shell 脚本打印该值?使用内置工具(例如printf
),或广泛使用的外部工具(例如xxd
, dc
, bc
, od
, hexdump
, etc.).
例如要打印十进制值,我可以使用xxd
(Vim 的一部分),例如在重击中:
-
获取第一个字节的值:
$ echo $((16#$(xxd -ps -s0 -l1 file.bin)))
176
For 2nd and forth bytes, increase -s
.
-
从所有 8 个字节中获取十进制值:
$ echo $((16#$(xxd -ps -s0 -l8 file.bin)))
-5732404399725297857
但是我想打印原始浮动值(0.123
) 在 Unix 系列系统上。
理想情况下使用一些单行代码(以使其作为脚本的一部分保持简单),这样我就可以将其分配给文本变量或在屏幕上打印该值。
我尝试过使用printf
(在 4 字节浮点数上以使其更简单),但它没有按预期工作:
$ xxd -p float.bin
6de7fb3d
$ printf "%.4f\n" 0x.$(xxd -p float.bin)
0.4293
$ printf "%.4f\n" 0x3dfbe76d
1039918957.0000
$ printf "%.4e\n" 0x3dfbe76d
1.0399e+09
根据这个在线转换器, 0x3dfbe76d
是相同的0.123
,所以十六进制值是相反的(什么xxd
实际上给出)。