Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to print float value from binary file in shell?

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).

like image 667
kenorb Avatar asked Apr 22 '16 10:04

kenorb


People also ask

How do I view bytes of a file?

Right-click the file and click Properties. The image below shows that you can determine the size of the file or files you have highlighted from in the file properties window. In this example, the chrome. jpg file is 18.5 KB (19,032 bytes), and that the size on disk is 20.0 KB (20,480 bytes).


2 Answers

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.

like image 194
Mark Setchell Avatar answered Oct 01 '22 02:10

Mark Setchell


od -f <filename>

That will dump your file as floats.

od is a standard Linux tool, and it's what I use. The manpage reads:

od - dump files in octal and other formats

like image 24
JellicleCat Avatar answered Oct 01 '22 04:10

JellicleCat