如何从shell中的二进制文件打印浮点值? [英] How to print float value from binary file in shell?
问题描述
我有一个二进制文件,包含双精度浮点数(8字节),或者只是浮点数(4字节),它是按照以下方式生成的:
$ python -c $'从结构导入包打开(file.bin,wb)为f:f.write(pack(< d,0.123))'
$ xxd file.bin
00000000:b072 6891 ed7c bf3f .rh .. |。?
我可以从Python打印回来:
$ python -c $'从结构导入unpack \打开(file.bin,rb)作为f:print(unpack(< d ,f.read(8)))'
(0.123,)
4字节浮点数,只需将< d
更改为< f
(提及为 float .bin
稍后)。
如何使用更清晰的方式(不使用Python)从shell脚本打印该值?使用内置的工具(如 printf
)或者广泛使用的外部工具(例如 xxd
, dc
, bc
, od
, / code>等)。
例如要打印十进制值,可以使用 xxd
(Vim的一部分),例如在Bash中:
获取第一个字节的值:
$ echo $((16#$(xxd -ps -s0 -l1 file.bin)))
176
对于第二和第四个字节,增加 -s
。
从所有8个字节获取小数值:
$ $ $ $ $
-5732404399725297857
$ $ $ $($ xx -ps -s0 -l8 file.bin))
但是我想在Unix系列系统上打印原始浮动值( 0.123
)。
理想情况下,使用一些单行(作为脚本的一部分保持简单),所以我可以将其分配到文本变量或打印屏幕上的值。
我已经尝试使用 printf
(在4字节浮点数上使其简化),但它没有如预期的那样工作:
$ pre $ code $ xxd -p float.bin
6de7fb3d
$ printf %.4f\\\
0x。$(xxd -p float.bin)
0.4293
$ printf%.4f\\\
0x3dfbe76d
1039918957.0000
$ printf %.4e \\\
0x3dfbe76d
1.0399e + 09
根据这个<一个href =http://gregstoll.dyndns.org/~gregstoll/floattohex/ =nofollow>在线转换器, 0x3dfbe76d
是与 0.123
相同,所以十六进制值反向( xxd
实际给出的值)。 b $ b
这并不使用 Python ,它是一个广泛使用的外部工具 Perl 。
perl -eprint pack('d>',0.123)> file.bin
perl -eprint unpack('d>',<>)< file.bin
0.123
或者你可以使用GNU od
utility,例如:
$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ 0000 $ 0.123
0000010
其中 -t
参数指定输出格式为浮点数( f
),后跟可选大小说明符( F
为浮点数, D
为double或 L
为长双),简而言之, -tfD
可以换成 -e
或 -F
。要仅打印没有地址的值,可以指定 -A n
。
I've binary file consisting double float (8 bytes) or just float (4 bytes) value which was generated in the following way:
$ 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..|.?
which I could print it back from Python via:
$ python -c $'from struct import unpack\nwith open("file.bin", "rb") as f: print(unpack("<d", f.read(8)))'
(0.123,)
The same for 4-byte float, just change <d
into <f
(mentioned as float.bin
later on).
How do I print that value from the shell script using cleaner way (without using Python)? Either using built-in tools (e.g. printf
), or wide-used external tools (e.g. xxd
, dc
, bc
, od
, hexdump
, etc.).
For example to print decimal values, I can use xxd
(part of Vim), e.g. in Bash:
get the value of first byte:
$ echo $((16#$(xxd -ps -s0 -l1 file.bin))) 176
For 2nd and forth bytes, increase
-s
.get decimal value from all 8 bytes:
$ echo $((16#$(xxd -ps -s0 -l8 file.bin))) -5732404399725297857
However I would like to print original floating value (0.123
) on Unix-family system.
Ideally using some one-liner (to keep it simple as part of the script), so I can assign it into text variable or print the value on the screen.
I've tried to use printf
(on the 4-byte float number to make it simpler), but it didn't work as expected:
$ 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
where according to this on-line converter, 0x3dfbe76d
is the same as 0.123
, so the hex values are in reverse (what xxd
actually gives).
This doesn't use Python and is a widely-used external tool, Perl.
perl -e "print pack('d>',0.123)" > file.bin
perl -e "print unpack('d>',<>)" < file.bin
0.123
Or you can use GNU od
utility, e.g.:
od -tfD file.bin
0000000 0.123
0000010
Where -t
parameter specifies the output format for floating-point number (f
) followed by optional size specifier (F
for float, D
for double or L
for long double), in short -tfD
can be replaced by -e
or -F
. To print only value without address, -A n
can be specified.
这篇关于如何从shell中的二进制文件打印浮点值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!