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


может кто-нибудь помочь мне, рассказывая, как преобразовать шестнадцатеричное число в десятичное число в скрипт? Например, я хочу преобразовать шестнадцатеричное число 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 "-")
6 99

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

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

еще один способ сделать это с помощью оболочки (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 ~]$ 

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

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

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

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

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

$ 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, конкретный.