如何从shell中的二进制文件打印浮点值? [英] How to print float value from binary file in shell?

查看:274
本文介绍了如何从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))

  • / ul>

    但是我想在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屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆