BASH conversione base da decimale a esadecimale


29

In Bash, come si fa una conversione base da decimale a un'altra base, in particolare esadecimale. Sembra facile andare dall'altra parte:

$ echo $((16#55))
85

Con una ricerca sul web, ho trovato uno script che esegue la matematica e la manipolazione dei caratteri per eseguire la conversione, e potrei usarlo come una funzione, ma avrei pensato che bash avrebbe già una conversione di base integrata - lo fa?


Risposte:


35

Con bash(o qualsiasi shell, a condizione che il printfcomando sia disponibile (un comando POSIX standard spesso incorporato nelle shell)):

printf '%x\n' 85

Con zsh, puoi anche fare:

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

Funziona con basi da 2 a 36 (con 0-9a-zmaiuscole e minuscole come le cifre).

Con ksh93, puoi usare:

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

Che funziona per basi da 2 a 64 (con 0-9a-zA-Z@_come cifre).

Con kshe zsh, c'è anche:

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

Anche se questo è limitato a basi fino a 36 in ksh88, zsh e pdksh e 64 in ksh93.

Nota che tutti questi sono limitati alle dimensioni degli longinteri sul tuo sistema ( intè con alcune shell). Per qualcosa di più grande, puoi usare bco dc.

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

Con basi supportate che vanno da 2 a un certo numero richiesto da POSIX per essere alto almeno fino a 99. Per basi superiori a 16, le cifre maggiori di 9 sono rappresentate come numeri decimali con spaziatura zero separati da spazio.

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

O lo stesso con dc( bcusato per essere (ed è ancora su alcuni sistemi) un wrapper in giro dc):

$ echo 30o123456p | dc
 04 17 05 06

Grazie. Esattamente quello che stavo cercando. (E imbarazzantemente semplice.)
Dave Rove,

E se vuoi fare una base arbitraria come puoi specificare con #?
flarn2006,

@ flarn2006. Con i bashbuiltin, puoi inserire numeri in qualsiasi base, ma non output in alcuna base diversa da 8, 10 e 16. Per altre basi, avresti bisogno di un'altra shell come zsho ksho utilizzare bc/dc.
Stéphane Chazelas,

1
@ StéphaneChazelas Davvero? È un po 'strano. Sembra quasi che fossero troppo pigri per programmare una sintassi per questo o qualcosa del genere; non è possibile che l'idea di emettere in una base non gli sia passata per la mente se implementasse l'immissione.
flarn2006,

alias hex="printf '%x\n'"
mwfearnley,

5

Usa printf:

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

Per assegnare il valore a una variabile utilizzare la sostituzione dei comandi:

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

4
Oppure, usa l' -vopzione per la printf -v foo "%d" $((16#BEEF)); echo $foo
stampa integrata

@Glenn L'uso di opzioni non standard (come -v) non è necessario qui; Lo eviterei.
Janis,

3
-veviterebbe la forcella e il tubo (in bash, non ksh93 che non si biforcherebbe qui come printfè incorporato). Si noti che $((16#55))non è neanche standard.
Stéphane Chazelas,

@ StéphaneChazelas, aspetta un minuto. Stai dicendo che ksh93 non va bene x=$(some_builtin)?
Glenn Jackman,

1
@glennjackman, sì, esegue solo il fork per eseguire comandi esterni.
Stéphane Chazelas,

2

Usa la sostituzione di espansione aritmetica integrata presente in tutte le shell conformi a POSIX, che è praticamente universale in questi giorni.

$ echo $((0xbc))
188

e

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

ATTENZIONE: In particolare nell'ultimo esempio l'espansione potrebbe causare risultati imprevisti: le cifre esadecimali nella variabile 'esadecimale' devono formare una costante esadecimale legale, altrimenti si verificano messaggi di errore potenzialmente oscuri. ad esempio, se "hex" fosse "0xdead", l'espansione aritmetica diventerebbe 0x0xdead, che non è interpretabile come costante. Naturalmente, in quel caso l'espansione aritmetica $ (($ hex)) farebbe il trucco. Viene lasciato come esercizio per il lettore creare la corrispondenza del modello di elaborazione della sottostringa semplice che rimuova un prefisso '0x' opzionale.


4
Stai facendo esattamente la stessa cosa che l'OP ha fatto nel suo esempio; sta cercando l' operazione inversa .
Thomas Guyot-Sionnest,

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.