Шістнадцятковий до десяткової у сценарії оболонки


126

Чи може хтось допомогти мені перетворити шістнадцятковий номер у десяткове число у сценарії оболонки?

Наприклад, я хочу перетворити шістнадцятковий номер 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 "-")

Навпаки : stackoverflow.com/questions/378829/… . По суті ті ж інструменти. І можливий дублікат на веб-сайті: superuser.com/questions/226163/…
Ciro Santilli 郝海东 冠状 病 六四 事件 事件

Відповіді:


314

Для перетворення з шістнадцяткових в десяткові є багато способів зробити це в оболонці або із зовнішньою програмою:

З :

$ 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 -e 'p "FF".to_i(16)'
255

з :

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

з :

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

з :

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

1
Що ? bc - Довільна мова калькулятора точності : зовнішня команда.
Жилль Кінот

10
А ТАК? саме ця мета моїх 4 команд, перш ніж ви зміните сенс свого питання.
Жилль Кінот

2
Чи є printfрішення POSIX? Якщо так, то це найкраще :)
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

3
У bash ви також можете використовувати $((0xff)), тобто з C-подібним шістнадцятковим префіксом замість 16#, хоча N#явно більш загальним.
Руслан

3
Перший приклад bash сприйнятливий до цілої помилки переповнення, наприклад, echo $((077E9F2DBF49D100001#FF))переповнює 64-бітну цілу граничну величину 2 ^ 64. bcсправляється з цим належним чином.
roblogic

39

Робота з дуже легкою вбудованою версією зайнятого ящика в Linux означає, що багато традиційних команд недоступні (bc, printf, dc, perl, python)

echo $((0x2f))
47

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

Кредит на Пітер Leung для цього рішення.


1
Гаразд, але остерігайтеся цілочисленної помилки переповнення, наприклад, echo $((0x077E9F2DBF49D100001))переповнює 64-бітну цілочисельну межу 2 ^ 64. bcсправляється з цим правильно
roblogic

13

Ще один спосіб зробити це за допомогою оболонки (bash або ksh, не працює з тире):

echo $((16#FF))
255

Що означає #символ? Чи є інші додатки чи документація, щоб ознайомитись із детальніше про її використання?
користувач1527227

1
Тут згадується: посилання . В кінці розділу 6.5 сказано: "... числа приймають форму [base #] n, де необов'язковою базовою є десятковий номер між 2 і 64, що представляє арифметичну базу, а n - число в цій базі. Якщо base # опущено, тоді використовується база 10. Цифри, що перевищують 9, представлені малими літерами, великими літерами, "@" та "_" у такому порядку. Якщо база менша або дорівнює 36, Малі та великі літери можуть використовуватися взаємозамінно для представлення чисел між 10 і 35. "
Томаш Фокс

11

З оболонки вам доступні різні інструменти. 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Команда «стіл вапняно». Він також буде брати вклад із stdin, якbc , але замість того, щоб використовувати "порядок операцій", він використовує стекинг ("зворотна польська") позначення. Ви даєте йому вхідні дані, які він додає до стеку, потім даєте їм операторів, які вискакують елементи зі стека, і відштовхуються від результатів.

У командах вище ми отримали наступне:

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

Ви можете побудувати казково складні математичні рішення за допомогою постійного струму. Це добре мати у своєму інструментарі для скриптів оболонок.


3

Повідомлення про помилку з'являється, коли змінні є нульовими (або порожніми):

$ 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`

Це змінить сценарій до цього:

#!/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, який не має такого обмеження.


3

У тирі та інших снарядах можна використовувати

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

перетворити шістнадцяткове число в десяткове. Це не bash, або ksh, специфічне.


1
наприкладprintf "%d" 0xff
lashgar
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.