web-dev-qa-db-ja.com

10進数から16進数へのBASHベースの変換

Bashでは、10進数からベース変換to別のベース、特に16進数をどのように変換しますか。逆に行くのは簡単なようです:

$ echo $((16#55))
85

ウェブ検索で、変換を行うために数学と文字操作を行うスクリプトを見つけました。それを関数として使用できますが、bashには既に組み込みの基本変換があると思っていました-しますか?

31
Dave Rove

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

ただし、ksh88、zsh、pdkshでは最大36、ksh93では最大64のベースに制限されています。

これらはすべて、システム上のlong整数(一部のシェルではintの整数)のサイズに制限されていることに注意してください。より大きなものについては、bcまたはdcを使用できます。

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

2から、POSIXで少なくとも99までの数値が必要な数値の範囲でサポートされている基数。16より大きい基数の場合、9より大きい数字は、スペースで区切られた0でパディングされた10進数として表されます。

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

またはdcと同じ(bcはかつてdcのラッパーでした(かつ、一部のシステムではまだ)):

$ echo 30o123456p | dc
 04 17 05 06
40

Printfを使用します。

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

値を変数に割り当てるには、コマンド置換を使用します。

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

すべてのPOSIX準拠シェルに存在する組み込みの算術拡張置換を使用します。これは、最近ではほとんど普遍的です。

$ echo $((0xbc))
188

そして

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

注意:特に最後の例では、展開により予期しない結果が生じる可能性があります-変​​数「hex」の16進数字は有効な16進定数を形成する必要があります。例えば「hex」が「0xdead」の場合、算術展開は0x0xdeadになり、定数として解釈できません。もちろん、その場合、算術展開$(($ hex))でうまくいきます。オプションの '0x'プレフィックスを削除する単純な部分文字列処理パターンマッチングを作成することは、読者の練習問題として残されています。

2

Awkを使用できます ベロアライブラリ

$ velour -n 'print n_baseconv(15, 10, 16)'
F

または:

$ velour -n 'print n_baseconv(ARGV[1], 10, 16)' 15
F
0
Steven Penny