Szesnastkowy na dziesiętny w skrypcie powłoki


126

Czy ktoś może mi pomóc w konwersji liczby szesnastkowej na dziesiętną w skrypcie powłoki?

Na przykład chcę przekonwertować liczbę szesnastkową bfca3000na dziesiętną za pomocą skryptu powłoki. Zasadniczo chcę różnicę dwóch liczb szesnastkowych.

Mój kod to:

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

Podczas wykonywania otrzymuję ten błąd:

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

Na odwrót: stackoverflow.com/questions/378829/… . Zasadniczo te same narzędzia. I możliwy duplikat w różnych witrynach: superuser.com/questions/226163/ ...
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Odpowiedzi:


314

Aby przekonwertować z szesnastkowego na dziesiętny, można to zrobić na wiele sposobów w powłoce lub w zewnętrznym programie:

Z :

$ echo $((16#FF))
255

z :

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

z :

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

z :

$ printf "%d\n" 0xFF
255

z :

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

z :

$ ruby -e 'p "FF".to_i(16)'
255

z :

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

z :

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

z :

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

1
Co ? bc to język kalkulatora o dowolnej precyzji : polecenie zewnętrzne.
Gilles Quenot

10
A więc ? to jest dokładnie celem moich 4 poleceń, zanim zmodyfikujesz znaczenie swojego pytania.
Gilles Quenot

2
Czy printfrozwiązanie jest zgodne z POSIX? Jeśli tak, to jest najlepsze :)
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

3
W bashu możesz także użyć $((0xff)), tj. Z przedrostkiem szesnastkowym podobnym do C zamiast 16#, chociaż N#jest to wyraźnie bardziej ogólne.
Rusłan

3
Pierwszy przykład basha jest podatny na błąd przepełnienia liczb całkowitych, np. echo $((077E9F2DBF49D100001#FF))Przekracza limit 64-bitowych liczb całkowitych 2 ^ 64. bcradzi sobie z tym prawidłowo.
roblogic

39

Radzenie sobie z bardzo lekką osadzoną wersją busybox w systemie Linux oznacza, że ​​wiele tradycyjnych poleceń nie jest dostępnych (bc, printf, dc, perl, python)

echo $((0x2f))
47

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

Problem zgłosili Peter Leung dla tego rozwiązania.


1
OK, ale uważaj na błąd przepełnienia liczb całkowitych, np. echo $((0x077E9F2DBF49D100001))Przekracza limit 64-bitowych liczb całkowitych wynoszący 2 ^ 64. bcradzi sobie z tym właściwie
roblogic

13

Jeszcze jeden sposób na zrobienie tego za pomocą powłoki (bash lub ksh, nie działa z myślnikiem):

echo $((16#FF))
255

Co oznacza ten #symbol? Czy są jakieś inne aplikacje lub dokumentacja, w których można przeczytać więcej na temat ich użycia?
user1527227

1
Jest tu wspomniane: link . Na końcu sekcji 6.5 jest napisane: „... liczby przyjmują postać [nr podstawy] n, gdzie opcjonalna podstawa jest liczbą dziesiętną od 2 do 64 reprezentującą podstawę arytmetyczną, an jest liczbą z tej podstawy. Jeśli podstawa # jest pomijana, a następnie używana jest podstawa 10. Cyfry większe niż 9 są reprezentowane przez małe litery, duże litery, „@” i „_”, w tej kolejności. Jeśli podstawa jest mniejsza lub równa 36, małe i duże litery mogą być używane zamiennie do oznaczania liczb od 10 do 35. ”
Tomás Fox

11

Z poziomu powłoki dostępne są różne narzędzia. Sputnick udzielił Ci doskonałego przeglądu dostępnych opcji, w oparciu o Twoje wstępne pytanie. Zdecydowanie zasługuje na głosy za czas, który spędził, udzielając wielu poprawnych odpowiedzi.

Jeszcze jeden, którego nie ma na jego liście:

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

Ale jeśli wszystko, co chcesz zrobić, to odjąć, po co przejmować się zmianą danych wejściowych na podstawę 10?

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

dcPolecenia jest „biurko oblicz”. Będzie również pobierał dane wejściowe ze stdin, na przykład bc, ale zamiast używać „kolejności operacji”, używa notacji stosowej („odwrotnej Polski”). Dajesz mu dane wejściowe, które dodaje do stosu, a następnie dajesz operatorom, które zdejmują elementy ze stosu i odkładają wyniki.

W powyższych poleceniach mamy:

  • 16i- mówi dc, aby zaakceptował dane wejściowe o podstawie 16 (szesnastkowej). Nie zmienia podstawy wyjściowej.
  • BFCA3000 - Twój numer początkowy
  • 17FF - losowa liczba szesnastkowa, którą wybrałem, aby odjąć od twojej początkowej liczby
  • - - weź dwie liczby, które zepchnęliśmy i odejmij późniejszą od poprzedniej, a następnie odłóż wynik z powrotem na stos
  • p- wydrukuj ostatni element na stosie. To nie zmienia stosu, więc ...
  • 10o - mówi dc, aby wypisał swoje wyjście w bazie „10”, ale pamiętaj, że nasz schemat numerowania wejść jest obecnie szesnastkowy, więc „10” oznacza „16”.
  • p - wydrukuj ponownie ostatni przedmiot ze stosu ... tym razem w formacie hex.

Za pomocą dc możesz tworzyć bajecznie złożone rozwiązania matematyczne. Dobrze jest mieć w swoim zestawie narzędzi do skryptów powłoki.


3

Zgłoszony błąd pojawia się, gdy zmienne są puste (lub puste):

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

Może się tak zdarzyć, ponieważ wartość nadana bc była nieprawidłowa. Może się tak zdarzyć, że bc potrzebuje WIELKICH liter. Musi BFCA3000, nie bfca3000. Można to łatwo naprawić w bash, po prostu użyj ^^rozszerzenia:

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

To zmieni skrypt na ten:

#!/bin/bash

var1="bfca3000"
var2="efca3250"

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

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

echo "Diference $var5"

Ale nie ma potrzeby używania bc [1], ponieważ bash mógłby bezpośrednio wykonać tłumaczenie i odejmowanie:

#!/bin/bash

var1="bfca3000"
var2="efca3250"

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

echo "Diference $var5"

[1] Uwaga: Zakładam, że wartości można przedstawić w 64-bitowej matematyce, ponieważ różnica została obliczona w bash w oryginalnym skrypcie. Bash jest ograniczony do liczb całkowitych mniejszych niż ((2 ** 63) -1), jeśli jest kompilowany na 64 bitach. To będzie jedyna różnica z bc, która nie ma takiego limitu.


3

W myślniku i innych muszlach możesz użyć

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

aby przekonwertować liczbę szesnastkową na dziesiętną. To nie jest specyficzne dla bash ani ksh.


1
np.printf "%d" 0xff
lashgar
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.