BASH базовое преобразование из десятичного в шестнадцатеричное


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 представляются в виде разделенных пробелами 0-запятых десятичных чисел.

$ 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 Использование нестандартных опций (вроде -v) здесь не нужно; Я бы избежал этого.
Янис

3
-vбудет избегать форка и трубы (в bash, а не в ksh93, который не будет форкнуть здесь, как printfвстроено). Обратите внимание, что $((16#55))это не является стандартным.
Стефан Шазелас

@ StéphaneChazelas, подожди минутку. Вы говорите, что ksh93 не форк для x=$(some_builtin)?
Гленн Джекман

1
@glennjackman, да, это только вилки для выполнения внешних команд.
Стефан Шазелас

2

Используйте встроенную замену Arithmetic Expansion, присутствующую во всех 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.