web-dev-qa-db-fra.com

Conversion de base BASH de décimal en hexadécimal

Dans Bash, comment fait-on une conversion de base de décimal vers une autre base, en particulier hexadécimale. Il semble facile d'aller dans l'autre sens:

$ echo $((16#55))
85

Avec une recherche sur le Web, j'ai trouvé un script qui fait le calcul et la manipulation des caractères pour effectuer la conversion, et je pourrais l'utiliser comme fonction, mais j'aurais pensé que bash aurait déjà une conversion de base intégrée - le fait-il?

31
Dave Rove

Avec bash (ou n'importe quel Shell, à condition que la commande printf soit disponible (une commande POSIX standard souvent construite dans les shells)):

printf '%x\n' 85

Avec zsh, vous pouvez également faire:

dec=85
hex=$(([##16]dec))

Cela fonctionne pour les bases de 2 à 36 (avec 0-9a-z insensible à la casse comme les chiffres).

Avec ksh93, vous pouvez utiliser:

dec=85
base54=$(printf %..54 "$dec")

Qui fonctionne pour les bases de 2 à 64 (avec 0-9a-zA-Z@_ comme chiffres).

Avec ksh et zsh, il y a aussi:

$ typeset -i34 x=123; echo "$x"
34#3l

Bien que cela soit limité aux bases jusqu'à 36 en ksh88, zsh et pdksh et 64 en ksh93.

Notez que tous ceux-ci sont limités à la taille des entiers long sur votre système (int avec certains shells). Pour quelque chose de plus grand, vous pouvez utiliser bc ou dc.

$ echo 'obase=16; 9999999999999999999999' | bc
21E19E0C9BAB23FFFFF
$ echo '16o 9999999999999999999999 p' | dc
21E19E0C9BAB23FFFFF

Avec des bases prises en charge allant de 2 à un certain nombre requis par POSIX pour être au moins aussi élevé que 99. Pour les bases supérieures à 16, les chiffres supérieurs à 9 sont représentés sous la forme de nombres décimaux séparés par des espaces et 0.

$ echo 'obase=30; 123456' | bc
 04 17 05 06

Ou même avec dc (bc était (et est toujours sur certains systèmes) un wrapper autour de dc):

$ echo 30o123456p | dc
 04 17 05 06
40
Stéphane Chazelas

Utilisez printf:

$ printf "%d %x\n" $((16#55)) $((10#85))
85 55

Pour affecter la valeur à une variable, utilisez la substitution de commande:

$ x=$( printf "%x" 85 ) ; echo $x
55
6
Janis

Utilisez la substitution d'expansion arithmétique intégrée présente dans tous les shells compatibles POSIX - qui est à peu près universelle de nos jours.

$ echo $((0xbc))
188

et

$ hex=dead
$ dec=$((0x$hex))
$ echo $dec
57005

ATTENTION: en particulier dans le dernier exemple, l'expansion peut entraîner des résultats inattendus - les chiffres hexadécimaux dans la variable "hex" doivent former une constante hexadécimale légale, sinon des messages d'erreur potentiellement obscurs se produisent. par exemple. si "hex" était "0xdead", l'expansion arithmétique deviendrait 0x0xdead, ce qui n'est pas interprétable comme une constante. Bien sûr, dans ce cas, l'expansion arithmétique $ (($ hex)) ferait l'affaire. Il est laissé comme exercice au lecteur de créer la correspondance de modèle de traitement de sous-chaîne simple qui supprimerait un préfixe "0x" facultatif.

2
Mark van der Pol

Vous pouvez utiliser l'awk bibliothèque Velour :

$ velour -n 'print n_baseconv(15, 10, 16)'
F

Ou:

$ velour -n 'print n_baseconv(ARGV[1], 10, 16)' 15
F
0
Steven Penny