Hexadecimal A Decimal en Shell Script


¿Puede alguien ayudarme a saber cómo convertir un número hexadecimal a un número decimal en un script de shell? Por ejemplo, quiero convertir el número hexadecimal bfca3000 a decimal usando un script de shell. Básicamente quiero la diferencia de dos números hexadecimales. Mi código es:

var3=`echo "ibase=16; $var1" | bc`
var4=`echo "ibase=16; $var2" | bc`
var5=$(($var4-$var3))               # [Line 48]

Al ejecutar, estoy obteniendo el error como:

Line 48: -: syntax error: operand expected (error token is "-")
Author: VenkateshJN, 2012-11-08

6 answers

Para convertir hex2dec, estas son muchas maneras de hacerlo en un shell o un script:

Con bash (cuidado con los espacios en blanco):

$ echo $(( 16#FF ))
255

Con bc :

$ echo "ibase=16; FF" | bc
255

Con perl:

$ perl -le 'print hex("FF");'
255

Con printf :

$ printf "%d\n" 0xFF
255

Con python:

$ python -c 'print(int("FF", 16))'
255

Con ruby:

$ ruby<<EOF
p "FF".to_i(16).to_s(10)
EOF
"255"

Con El nodo .js :

$ nodejs <<< "console.log(parseInt('FF', 16))"
255

Con rinoceronte :

$ rhino<<EOF
print(parseInt('FF', 16))
EOF
...
255

Con groovy :

$ groovy -e 'println Integer.parseInt("FF",16)'
255
 229
Author: Gilles Quenot,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-24 13:14:58

Tratar con una versión embebida muy ligera de busybox en Linux significa que muchos de los comandos tradicionales no están disponibles (bc, printf, dc, perl, python)

echo $((0x2f))
47

hexNum=2f
echo $((0x${hexNum}))
47

Crédito a Peter Leung para esta solución.

 32
Author: hinekyle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-04 12:48:47

Una forma más de hacerlo usando el shell (bash o ksh, no funciona con dash):

echo $((16#FF))
255
 12
Author: Tomás Fox,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-14 07:26:49

Varias herramientas están disponibles para usted desde dentro de un shell. Sputnick le ha dado un excelente resumen de sus opciones, basado en su pregunta inicial. Definitivamente merece votos por el tiempo que pasó dándote múltiples respuestas correctas.

Uno más que no está en su lista:

[ghoti@pc ~]$ dc -e '16i BFCA3000 p'
3217698816

Pero si todo lo que quiere hacer es restar, ¿por qué molestarse en cambiar la entrada a base 10?

[ghoti@pc ~]$ dc -e '16i BFCA3000 17FF - p 10o p'
3217692673
BFCA1801
[ghoti@pc ~]$ 

El comando dc es "desk calc". También tomará la entrada de stdin, como bc, pero en lugar de usar "orden de operaciones", usa la notación de apilamiento ("polaco inverso"). Le das entradas que agrega a una pila, luego le das operadores que sacan elementos de la pila y devuelven los resultados.

En los comandos anteriores tenemos lo siguiente:

  • 16i -- le dice a dc que acepte entrada en base 16 (hexadecimal). No cambia la base de salida.
  • BFCA3000 -- su número inicial
  • 17FF -- a al azar número hexadecimal que elegí para restar de su número inicial
  • - -- tome los dos números que hemos empujado, y reste el último del anterior, luego empuje el resultado de nuevo a la pila
  • p -- imprime el último elemento de la pila. Esto no cambia la pila, así que...
  • 10o -- le dice a dc que imprima su salida en base "10", pero recuerde que nuestro esquema de numeración de entrada es actualmente hexadecimal, por lo que" 10 " significa "16".
  • p -- vuelva a imprimir el último elemento de la pila ... esta vez en hex.

Puede construir soluciones matemáticas fabulosamente complejas con dc. Es una buena cosa para tener en su caja de herramientas para scripts de shell.

 11
Author: ghoti,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-11-08 00:21:01

El error reportado aparece cuando las variables son null (o vacías):

$ unset var3 var4; var5=$(($var4-$var3))
bash: -: syntax error: operand expected (error token is "-")

Eso podría suceder porque el valor dado a bc era incorrecto. Eso bien podría ser que bc necesita valores en mayúsculas. Necesita BFCA3000, no bfca3000. Eso se arregla fácilmente en bash, solo usa la expansión ^^:

var3=bfca3000; var3=`echo "ibase=16; ${var1^^}" | bc`

Eso cambiará el script a esto:

#!/bin/bash

var1="bfca3000"
var2="efca3250"

var3="$(echo "ibase=16; ${var1^^}" | bc)"
var4="$(echo "ibase=16; ${var2^^}" | bc)"

var5="$(($var4-$var3))"

echo "Diference $var5"

Pero no hay necesidad de usar bc [1], ya que bash podría realizar la traducción y substracción directamente:

#!/bin/bash

var1="bfca3000"
var2="efca3250"

var5="$(( 16#$var2 - 16#$var1 ))"

echo "Diference $var5"

[1]Nota: Estoy asumiendo que los valores podrían representarse en matemáticas de 64 bits, ya que la diferencia se calculó en bash en su script original. Bash está limitado a enteros menores que ((2**63)-1) si se compilan en 64 bits. Esa será la única diferencia con bc que no tiene tal límite.

 3
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-29 22:34:54

En dash y otros shells, puedes usar

printf "%d\n" (your hexadecimal number)

Para convertir un número hexadecimal a decimal. Esto no es bash, o ksh, específico.

 1
Author: novice,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-12 21:36:35