web-dev-qa-db-fra.com

Hexadécimal à décimal dans un script shell

Est-ce que quelqu'un peut m'aider à convertir un nombre hexadécimal en nombre décimal dans un script Shell?

Par exemple, je veux convertir le nombre hexadécimal bfca3000 en décimal à l'aide d'un script Shell. Je veux fondamentalement la différence de deux nombres hexadécimaux.

Mon code est:

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

Lors de l'exécution, j'obtiens cette erreur:

Line 48: -: syntax error: operand expected (error token is "-")
116
VenkateshJN

Pour convertir un fichier hexadécimal en fichier décimal, il existe plusieurs façons de le faire dans le shell ou avec un programme externe:

Avec bash :

$ echo $((16#FF))
255

avec bc :

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

avec Perl :

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

avec printf :

$ printf "%d\n" 0xFF
255

avec python :

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

avec Ruby :

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

avec node.js :

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

avec rhino :

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

avec groovy :

$ groovy -e 'println Integer.parseInt("FF",16)'
255
277
Gilles Quenot

Traiter avec une version embarquée très légère de busybox sous Linux signifie que beaucoup des commandes traditionnelles ne sont pas disponibles (bc, printf, dc, Perl, python).

echo $((0x2f))
47

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

Nous remercions Peter Leung pour cette solution.

35
hinekyle

Une autre façon de faire en utilisant le shell (bash ou ksh, ne fonctionne pas avec dash):

echo $((16#FF))
255
13
Tomás Fox

Divers outils sont à votre disposition depuis un shell. Sputnick vous a donné un excellent aperçu de vos options, en fonction de votre question initiale. Il mérite certainement des votes pour le temps qu'il a passé à vous donner plusieurs réponses correctes.

Un de plus qui ne figure pas sur sa liste:

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

Mais si tout ce que vous voulez faire est de soustraire, pourquoi ne pas changer l’entrée en base 10?

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

La commande dc est "desk calc". Il utilisera également l'entrée stdin, comme bc, mais au lieu d'utiliser "l'ordre des opérations", il utilise la notation d'empilement ("reverse Polish"). Vous lui donnez des entrées qu'il ajoute à une pile, puis vous lui donnez des opérateurs qui extraient des éléments de la pile et un push sur les résultats.

Dans les commandes ci-dessus, nous avons ce qui suit:

  • 16i - indique à dc d'accepter les entrées en base 16 (hexadécimales). Ne change pas la base de sortie.
  • BFCA3000 - votre numéro initial
  • 17FF - un nombre hexadécimal aléatoire que j'ai choisi de soustraire de votre nombre initial
  • - - prenez les deux nombres que nous avons indiqués et soustrayez le plus récent du précédent, puis repoussez le résultat la pile
  • p - affiche le dernier élément de la pile. Cela ne change pas la pile, alors ...
  • 10o - indique à dc d'imprimer sa sortie en base "10", mais rappelez-vous que notre schéma de numérotation d'entrée est actuellement hexadécimal, donc " 10 "signifie" 16 ".
  • p - affiche le dernier élément de la pile à nouveau ... cette fois en hexadécimal.

Vous pouvez construire des solutions mathématiques complexes avec DC. C'est une bonne chose d'avoir dans votre boîte à outils pour les scripts Shell.

11
ghoti

L'erreur signalée apparaît lorsque les variables sont nulles (ou vides):

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

Cela pourrait arriver parce que la valeur donnée à bc était incorrecte. Cela pourrait bien être que bc a besoin des valeurs UPPERcase. Il faut BFCA3000, pas bfca3000. Ceci est facilement corrigé dans bash, utilisez simplement l'extension ^^:

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

Cela changera le script en ceci:

#!/bin/bash

var1="bfca3000"
var2="efca3250"

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

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

echo "Diference $var5"

Mais il n’est pas nécessaire d’utiliser bc [1], car bash pourrait effectuer directement la traduction et la soustraction:

#!/bin/bash

var1="bfca3000"
var2="efca3250"

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

echo "Diference $var5"

[1]Remarque: je suppose que les valeurs pourraient être représentées en calcul 64 bits, car la différence a été calculée sous bash dans votre script d'origine. Bash est limité à un nombre entier inférieur à ((2 ** 63) -1) s'il est compilé en 64 bits. Ce sera la seule différence avec bc qui n’a pas une telle limite.

3
user2350426

En tiret et autres coquillages, vous pouvez utiliser

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

convertir un nombre hexadécimal en décimal. Ce n'est pas bash, ni ksh, spécifique.

2
novice