はじめに
10進数からn進数(2~64進数)に変換するBashスクリプトの関数です。今回は引数チェックも入れました。Bash 4.4.12で動作を確認しています。
参考記事→Bashだけで16進数・10進数・2進数間の相互変換を行う
コード
conv_digit.sh
# Usage: conv_digit 17 2 # -> 10001
# Usage: conv_digit 31 16 # -> 1f
function conv_digit()
{
local natural digit quotient surplus sign c64 result
c64='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ@_'
[[ ! $1 ]] && return
if [[ ! $1 =~ ^[+\-]?[0-9]+$ ]]
then
echo "${FUNCNAME[0]}($1,$2): Arg 1 is invalid. call from ${FUNCNAME[1]}():${BASH_LINENO[0]}">&2
return -1
fi
[[ $1 -lt 0 ]] && { natural=-$1;sign=-; } || natural=$1
if [[ $2 ]]
then
if [[ ! $2 =~ ^[0-9]+$ || $2 -lt 2 || $2 -gt 64 ]]
then
echo "${FUNCNAME[0]}($1,$2): Arg 2 is invalid. call from ${FUNCNAME[1]}():${BASH_LINENO[0]}">&2
return -1
else
digit=$2
fi
else
digit=10
fi
echo -n $sign
while :
do
surplus=$(($natural%$digit))
natural=$(($natural/$digit))
result=${c64:$surplus:1}$result
[[ $natural -eq 0 ]] && break
done
echo $result
}
使い方
.sh
$ conv_digit 17 2
10001
$ conv_digit 31 16
1f
$ conv_digit 31
31
n進数から10進数にするにはBashの組み込み機能で行なえます。
.sh
$ echo $((16#1f))
31
$ echo $((16#$(conv_digit 31 16)))
31
補足
第一引数は変換する10進数自然数のつもりでしたが、先頭に0がつく数字は8進数として、先頭にマイナス記号(-)がつく数字は負の数として認識されるようですが、完全には動作を確認していません。小数は扱えません。
なお第二引数は進数を指定します。2から64の整数のみを指定でき、負の値や小数はエラーになります。指定しない場合は10として扱われます。
諸注意
コードはご自由に使って頂いて構いませんが、一切の保証はいたしません。