Шестнадцатеричных в десятичные в shell-скрипт

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

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 "-")

6 ответов


чтобы преобразовать hex2dec, это много способов сделать это в оболочке или скрипте:

С Баш (остерегайтесь пробелов):

$ echo $(( 16#FF ))
255

С bc:

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

С perl:

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

С printf :

$ printf "%d\n" 0xFF
255

С python:

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

С Рубин:

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

С узел.js:

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

С носорог:

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

С в Groovy:

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

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

echo $((0x2f))
47

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

кредит Питер Люн для этого решения.


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

echo $((16#FF))
255

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

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

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

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

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

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

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

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

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


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

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

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

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

это изменит сценарий на это:

#!/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 в вашем исходном скрипте. Bash ограничен целыми числами меньше ((2* * 63) -1), если скомпилирован в 64 битах. Это будет единственная разница с bc, которая не имеет такого предела.


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

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

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