¿Cómo imprimir un valor flotante desde un archivo binario en shell?
Tengo un archivo binario que consiste en un valor de doble flotante (8 bytes) o solo flotante (4 bytes) que se generó de la siguiente manera:
$ python -c que podría imprimir desde Python a través de:
$ python -c Lo mismo para flotador de 4 bytes, solo cambie<d
dentro<f
(mencionado comofloat.bin
mas tarde).
¿Cómo imprimo ese valor desde el script de shell usando una forma más limpia (sin usar Python)? Ya sea utilizando herramientas integradas (p. Ej.printf
) o herramientas externas muy utilizadas (p. ej.xxd
, dc
, bc
, od
, hexdump
, etc.)
Por ejemplo, para imprimir valores decimales, puedo usarxxd
(parte de Vim), p. en Bash:
obtener el valor del primer byte:
$ echo $((16#$(xxd -ps -s0 -l1 file.bin)))
176
Para los bytes segundo y cuarto, aumente-s
.
obtener el valor decimal de los 8 bytes:
$ echo $((16#$(xxd -ps -s0 -l8 file.bin)))
-5732404399725297857
Sin embargo, me gustaría imprimir el valor flotante original (0.123
) en el sistema Unix-family. Lo ideal es usar una sola línea (para que sea simple como parte del guión), de modo que pueda asignarla a una variable de texto o imprimir el valor en la pantalla.
He intentado usarprintf
(en el número flotante de 4 bytes para hacerlo más simple), pero no funcionó como se esperaba:
$ 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
donde de acuerdo a estoconvertidor en línea, 0x3dfbe76d
es lo mismo que0.123
, entonces los valores hexadecimales están en reversa (quéxxd
en realidad da).
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..|.?
que podría imprimir desde Python a través de:
$ python -c $'from struct import unpack\nwith open("file.bin", "rb") as f: print(unpack("<d", f.read(8)))'
(0.123,)
Lo mismo para flotador de 4 bytes, solo cambie<d
dentro<f
(mencionado comofloat.bin
mas tarde).
¿Cómo imprimo ese valor desde el script de shell usando una forma más limpia (sin usar Python)? Ya sea utilizando herramientas integradas (p. Ej.printf
) o herramientas externas muy utilizadas (p. ej.xxd
, dc
, bc
, od
, hexdump
, etc.)
Por ejemplo, para imprimir valores decimales, puedo usarxxd
(parte de Vim), p. en Bash:
obtener el valor del primer byte:
$ echo $((16#$(xxd -ps -s0 -l1 file.bin)))
176
Para los bytes segundo y cuarto, aumente-s
.
obtener el valor decimal de los 8 bytes:
$ echo $((16#$(xxd -ps -s0 -l8 file.bin)))
-5732404399725297857
Sin embargo, me gustaría imprimir el valor flotante original (0.123
) en el sistema Unix-family. Lo ideal es usar una sola línea (para que sea simple como parte del guión), de modo que pueda asignarla a una variable de texto o imprimir el valor en la pantalla.
He intentado usarprintf
(en el número flotante de 4 bytes para hacerlo más simple), pero no funcionó como se esperaba:
$ 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
donde de acuerdo a estoconvertidor en línea, 0x3dfbe76d
es lo mismo que0.123
, entonces los valores hexadecimales están en reversa (quéxxd
en realidad da).
from struct import unpack\nwith open("file.bin", "rb") as f: print(unpack("<d", f.read(8)))'
(0.123,)
Lo mismo para flotador de 4 bytes, solo cambie<d
dentro<f
(mencionado comofloat.bin
mas tarde).
¿Cómo imprimo ese valor desde el script de shell usando una forma más limpia (sin usar Python)? Ya sea utilizando herramientas integradas (p. Ej.printf
) o herramientas externas muy utilizadas (p. ej.xxd
, dc
, bc
, od
, hexdump
, etc.)
Por ejemplo, para imprimir valores decimales, puedo usarxxd
(parte de Vim), p. en Bash:
obtener el valor del primer byte:
$ echo $((16#$(xxd -ps -s0 -l1 file.bin)))
176
Para los bytes segundo y cuarto, aumente-s
.
obtener el valor decimal de los 8 bytes:
$ echo $((16#$(xxd -ps -s0 -l8 file.bin)))
-5732404399725297857
Sin embargo, me gustaría imprimir el valor flotante original (0.123
) en el sistema Unix-family. Lo ideal es usar una sola línea (para que sea simple como parte del guión), de modo que pueda asignarla a una variable de texto o imprimir el valor en la pantalla.
He intentado usarprintf
(en el número flotante de 4 bytes para hacerlo más simple), pero no funcionó como se esperaba:
$ 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
donde de acuerdo a estoconvertidor en línea, 0x3dfbe76d
es lo mismo que0.123
, entonces los valores hexadecimales están en reversa (quéxxd
en realidad da).
que podría imprimir desde Python a través de:
$ python -c $'from struct import unpack\nwith open("file.bin", "rb") as f: print(unpack("<d", f.read(8)))'
(0.123,)
Lo mismo para flotador de 4 bytes, solo cambie<d
dentro<f
(mencionado comofloat.bin
mas tarde).
¿Cómo imprimo ese valor desde el script de shell usando una forma más limpia (sin usar Python)? Ya sea utilizando herramientas integradas (p. Ej.printf
) o herramientas externas muy utilizadas (p. ej.xxd
, dc
, bc
, od
, hexdump
, etc.)
Por ejemplo, para imprimir valores decimales, puedo usarxxd
(parte de Vim), p. en Bash:
obtener el valor del primer byte:
$ echo $((16#$(xxd -ps -s0 -l1 file.bin)))
176
Para los bytes segundo y cuarto, aumente-s
.
obtener el valor decimal de los 8 bytes:
$ echo $((16#$(xxd -ps -s0 -l8 file.bin)))
-5732404399725297857
Sin embargo, me gustaría imprimir el valor flotante original (0.123
) en el sistema Unix-family. Lo ideal es usar una sola línea (para que sea simple como parte del guión), de modo que pueda asignarla a una variable de texto o imprimir el valor en la pantalla.
He intentado usarprintf
(en el número flotante de 4 bytes para hacerlo más simple), pero no funcionó como se esperaba:
$ 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
donde de acuerdo a estoconvertidor en línea, 0x3dfbe76d
es lo mismo que0.123
, entonces los valores hexadecimales están en reversa (quéxxd
en realidad da).