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 "-")
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
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.
Une autre façon de faire en utilisant le shell (bash ou ksh, ne fonctionne pas avec dash):
echo $((16#FF))
255
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 initial17FF
- 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 pilep
- 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.
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.
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.