Шестнадцатеричный до десятичного в оболочке Script

Может ли кто-нибудь помочь мне преобразовать шестнадцатеричное число в десятичное число в сценарии оболочки?

Например, я хочу преобразовать шестнадцатеричное число bfca3000 в десятичное с помощью сценария оболочки. Я в основном хочу разницу двух шестнадцатеричных чисел.

Мой код:

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

При выполнении я получаю эту ошибку:

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

Ответ 1

Чтобы преобразовать из шестнадцатеричного в десятичное, есть много способов сделать это в оболочке или с внешней программой:

С :

$ echo $((16#FF))
255

с :

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

с помощью :

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

с :

$ printf "%d\n" 0xFF
255

с :

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

с :

$ ruby<<EOF
p "FF".to_i(16).to_s(10)
EOF
"255"

с :

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

с :

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

с :

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

Ответ 2

Работа с очень легкой встроенной версией busybox в Linux означает, что многие традиционные команды недоступны (bc, printf, dc, perl, python)

echo $((0x2f))
47

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

Кредит Peter Leung для этого решения.

Ответ 3

Еще один способ сделать это с помощью оболочки (bash или ksh, не работает с тире):

echo $((16#FF))
255

Ответ 4

Различные инструменты доступны вам изнутри оболочки. Sputnick предоставил вам отличный обзор ваших вариантов, исходя из вашего первоначального вопроса. Он определенно заслуживает голосов за то время, которое он провел, давая вам несколько правильных ответов.

Еще одно, что не в его списке:

[[email protected] ~]$ dc -e '16i BFCA3000 p'
3217698816

Но если все, что вы хотите сделать, это вычесть, зачем беспокоить изменение входа на базовую 10?

[[email protected] ~]$ dc -e '16i BFCA3000 17FF - p 10o p'
3217692673
BFCA1801
[[email protected] ~]$ 

Команда dc - это "настольный расчет". Он также будет принимать входные данные от stdin, например bc, но вместо использования "порядка операций" он использует нотацию сложения ( "обратное польский" ). Вы даете ему входы, которые он добавляет к стеку, а затем дайте ему операторы, которые вытесняют элементы из стека и возвращают результаты.

В приведенных выше командах есть следующее:

  • 16i - указывает dc принимать входные данные в базе 16 (шестнадцатеричный). Не меняет выходную базу.
  • BFCA3000 - ваш начальный номер
  • 17FF - случайный шестнадцатеричный номер, который я выбрал для вычитания из вашего начального номера
  • - - возьмите два числа, которые мы нажали, и вычтем более поздний из предыдущего, затем вернем результат обратно в стек
  • p - распечатать последний элемент в стеке. Это не меняет стек, поэтому...
  • 10o - сообщает dc распечатать свой вывод в базе "10", но помните, что наша схема ввода-ввода в настоящее время является шестнадцатеричной, поэтому "10" означает "16".
  • p - снова напечатать последний элемент в стеке... на этот раз в шестнадцатеричном формате.

Вы можете построить сказочно сложные математические решения с dc. Это хорошая вещь, чтобы иметь в своей панели инструментов сценарии оболочки.

Ответ 5

Сообщаемая ошибка появляется, когда переменные являются пустыми (или пустыми):

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

Это может произойти, потому что значение, данное bc, неверно. Вполне возможно, что для bc нужны значения UPPERcase. Он нуждается в BFCA3000, а не BFCA3000. Это легко установить в bash, просто используйте расширение ^^:

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

Это изменит script на следующее:

#!/bin/bash

var1="bfca3000"
var2="efca3250"

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

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

echo "Diference $var5"

Но нет необходимости использовать bc [1], так как bash может выполнять перевод и вычитание напрямую:

#!/bin/bash

var1="bfca3000"
var2="efca3250"

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

echo "Diference $var5"

[1] Примечание. Я предполагаю, что значения могут быть представлены в 64-битной математике, так как разница была рассчитана в bash в исходном script. bash ограничивается целыми числами меньше ((2 ** 63) -1), если скомпилировано в 64 бита. Это будет единственная разница с bc, которая не имеет такого предела.

Ответ 6

В тире и других оболочках вы можете использовать

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

чтобы преобразовать шестнадцатеричное число в десятичное. Это не bash, или ksh, specific.

Ответ 7

Я хотел бы прокомментировать ответ ghoti о dc но у меня еще нет 50 репутации, чтобы сделать это, поэтому все, что я должен сказать о его объяснении:

echo 112197126661204141317879656966534752522P | dc