Konwersja bazy BASH z dziesiętnej na szesnastkową


29

W Bash, w jaki sposób wykonuje się konwersję podstawy z dziesiętnej na inną podstawę, zwłaszcza szesnastkową. Wydaje się, że łatwo jest pójść w drugą stronę:

$ echo $((16#55))
85

Podczas wyszukiwania w Internecie znalazłem skrypt, który wykonuje matematykę i manipulacje postaciami w celu konwersji i mógłbym użyć tego jako funkcji, ale pomyślałem, że bash miałby już wbudowaną podstawową konwersję - czy to?


Odpowiedzi:


35

Za pomocą bash(lub dowolnej powłoki, pod warunkiem, że printfpolecenie jest dostępne (standardowe polecenie POSIX często wbudowane w powłoki)):

printf '%x\n' 85

Za pomocą zshmożesz także:

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

Działa to dla baz od 2 do 36 (z 0-9a-zrozróżnianiem wielkości liter jak cyfry).

Za pomocą ksh93możesz użyć:

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

Który działa dla baz od 2 do 64 (z 0-9a-zA-Z@_cyframi).

Z kshi zshsą też:

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

Chociaż jest to ograniczone do baz do 36 w ksh88, zsh i pdksh i 64 w ksh93.

Zauważ, że wszystkie one są ograniczone do wielkości longliczb całkowitych w twoim systemie ( intz niektórymi powłokami). Do czegokolwiek większego możesz użyć bclub dc.

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

Przy obsługiwanych podstawach od 2 do pewnej liczby wymaganej przez POSIX do co najmniej tak wysokiej, jak 99. W przypadku zasad większych niż 16, cyfry większe niż 9 są reprezentowane jako oddzielone spacjami liczby dziesiętne uzupełnione zerami.

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

Lub to samo z dc( bckiedyś (i nadal jest w niektórych systemach) otoką dc):

$ echo 30o123456p | dc
 04 17 05 06

Dzięki. Właśnie tego szukałem. (I żenująco proste.)
Dave Rove

Co jeśli chcesz zrobić dowolną bazę, jaką możesz określić #?
flarn2006 27.09.16

@ flarn2006. Z bashpoleceń wbudowanych, można wejść liczby w dowolnym systemie, ale nie wyjście w jakiejkolwiek innej podstawy niż 8, 10 i 16. W przypadku innych baz, to by trzeba inną powłokę podobnego zshlub kshlub wykorzystanie bc/dc.
Stéphane Chazelas

1
@ StéphaneChazelas Naprawdę? To trochę dziwne. Wygląda na to, że byli zbyt leniwi, aby zaprogramować składnię lub coś takiego; nie ma mowy, aby pomysł wysyłania danych do jakiejkolwiek bazy nie przyszedł im do głowy, gdyby wdrożyli wprowadzanie danych.
flarn2006

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

5

Użyj printf:

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

Aby przypisać wartość do zmiennej, użyj podstawienia polecenia:

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

4
Lub skorzystaj z -vopcji wbudowanego printf:printf -v foo "%d" $((16#BEEF)); echo $foo
glenn jackman

@Glenn Korzystanie z niestandardowych opcji (takich jak -v) nie jest tutaj konieczne; Unikałbym tego.
Janis

3
-vunikałby rozwidlenia i potoku (w bash, nie ksh93, który nie rozwidliby się tutaj, jak printfjest wbudowany). Pamiętaj, że $((16#55))nie jest to również standard.
Stéphane Chazelas,

@ StéphaneChazelas, poczekaj chwilę. Czy mówisz, że ksh93 nie rozwidla się x=$(some_builtin)?
glenn jackman

1
@glennjackman, tak, tylko forki do wykonywania poleceń zewnętrznych.
Stéphane Chazelas,

2

Użyj wbudowanego podstawienia rozszerzenia arytmetycznego obecnego we wszystkich powłokach zgodnych z POSIX - co jest obecnie dość uniwersalne.

$ echo $((0xbc))
188

i

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

UWAGA: Szczególnie w ostatnim przykładzie rozszerzenie może powodować nieoczekiwane wyniki - cyfry szesnastkowe w zmiennej „hex” muszą tworzyć legalną stałą szesnastkową, w przeciwnym razie mogą wystąpić niejasne komunikaty o błędach. np. jeśli „hex” to „0xdead”, rozszerzenie arytmetyczne zmieniłoby się na 0x0xdead, którego nie można interpretować jako stałą. Oczywiście w takim przypadku arytmetyczna ekspansja $ (($ hex)) załatwi sprawę. Pozostawia się czytelnikowi ćwiczenie polegające na stworzeniu prostego dopasowania wzorca przetwarzania podciągu, który usunąłby opcjonalny prefiks „0x”.


4
Robisz dokładnie to samo, co OP zrobił w swoim przykładzie; szuka odwrotnej operacji.
Thomas Guyot-Sionnest

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.