Перетворення базової бази з десяткової в шестнадцяткову


29

У Bash, як можна перетворити базу з десяткової в іншу базу, особливо шістнадцяткову. Здається легко піти іншим шляхом:

$ echo $((16#55))
85

За допомогою веб-пошуку я знайшов сценарій, який виконує перетворення математики та символів для перетворення, і я міг би використовувати це як функцію, але я би подумав, що bash вже матиме вбудовану базову конверсію - робить це?


Відповіді:


35

З bash(або будь-якою оболонкою, за умови наявності printfкоманди (стандартна команда POSIX, часто вбудована в оболонки)):

printf '%x\n' 85

Завдяки цьому zshви також можете:

dec=85
hex=$(([##16]dec))

Це працює для баз від 2 до 36 (з 0-9a-zрегістром, як цифри).

З ksh93, ви можете використовувати:

dec=85
base54=$(printf %..54 "$dec")

Який працює для баз від 2 до 64 (з 0-9a-zA-Z@_цифрами).

З kshі zsh, є також:

$ typeset -i34 x=123; echo "$x"
34#3l

Хоча це обмежено базами до 36 в ksh88, zsh і pdksh і 64 в ksh93.

Зауважте, що всі вони обмежені розміром longцілих чисел у вашій системі ( intз деякими оболонками). Для чогось більшого ви можете використовувати bcабо dc.

$ echo 'obase=16; 9999999999999999999999' | bc
21E19E0C9BAB23FFFFF
$ echo '16o 9999999999999999999999 p' | dc
21E19E0C9BAB23FFFFF

Для підтримуваних баз від 2 до деякого числа, вимагається POSIX, щонайменше до 99. Для баз більше 16 цифри, що перевищують 9, представлені у вигляді десяткових чисел, розділених пробілами, десяткові цифри.

$ echo 'obase=30; 123456' | bc
 04 17 05 06

Або те саме з dc( bcраніше був (і все ще є в деяких системах) обгорткою dc):

$ echo 30o123456p | dc
 04 17 05 06

Спасибі. Саме те, що я шукав. (І бентежно просто.)
Дейв Роув

Що робити, якщо ви хочете зробити довільну базу, як ви можете вказати #?
flarn2006

@ flarn2006. З bashвбудованих команд, ви можете введення чисел в будь-який системі числення, але не виводиться в будь-якій підставі, крім 8, 10 і 16. Для інших баз, вам буде потрібно ще один снаряд , як zshабо kshабо використання bc/dc.
Стефан Шазелас

1
@ StéphaneChazelas Дійсно? Це щось дивно. Майже здається, що вони лінувалися програмувати синтаксис для цього чи чогось іншого; немає ніякої ідеї про вихід у будь-яку базу не перешкоджало їхній думці, якби вони реалізували введення.
flarn2006

alias hex="printf '%x\n'"
mwfearnley

5

Використовуйте printf:

$ printf "%d %x\n" $((16#55)) $((10#85))
85 55

Щоб призначити значення змінній, використовуйте підстановку команди:

$ x=$( printf "%x" 85 ) ; echo $x
55

4
Або скористайтеся -vопцією для вбудованого printf:printf -v foo "%d" $((16#BEEF)); echo $foo
glenn jackman

@Glenn Використання нестандартних параметрів (наприклад -v) тут непотрібне; Я б цього уникав.
Яніс

3
-vдозволить уникнути вилки та труби (в bash, не ksh93, яка б тут не роздвоялася, як printfвбудована). Зверніть увагу, що теж $((16#55))не є стандартним.
Стефан Шазелас

@ StéphaneChazelas, почекай хвилинку. Ви кажете, що ksh93 не розщедриться x=$(some_builtin)?
Глен Джекман

1
@glennjackman, так, він лише роздвоєний для виконання зовнішніх команд.
Стефан Шазелас

2

Використовуйте вбудовану заміну Арифметичного розширення, наявну у всіх сумісних оболонках POSIX - що в ці дні є майже універсальним.

$ echo $((0xbc))
188

і

$ hex=dead
$ dec=$((0x$hex))
$ echo $dec
57005

ПОПЕРЕДЖЕННЯ. Особливо в останньому прикладі розширення може спричинити несподівані результати - шістнадцяткові цифри змінної 'hex' повинні утворювати законну шестнадцяткову константу, інакше трапляються потенційно незрозумілі повідомлення про помилки. наприклад, якби "hex" був "0xdead", арифметичне розширення стане 0x0xdead, що не інтерпретується як константа. Звичайно, у такому випадку арифметичне розширення $ (($ hex)) зробить свою справу. Для читача залишається вправа створити просту відповідність схеми обробки підрядків, яка видалила б необов'язковий префікс "0x".


4
Ви робите саме те, що зробив ОП у своєму прикладі; він шукає зворотну операцію.
Томас Гайо-Сіоннест

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