经常涉及到进制的转换,比如线上处理问题时候经常需要转换线程id到16进制.
1.进制转换
2.1.shell运算
Shell 运算把一个数字从给定的进制转换位十进制.如果数字以运算展开式的形式提供,那么假定它带有十进制符号,除非 它前面带有 0(这种情况假定是八进制)或 0x(这种情况假定是十六进制)
1
2
3
4
xiaobaoqiu@xiaobaoqiu:~/myshell$ echo $((010))
8
xiaobaoqiu@xiaobaoqiu:~/myshell$ echo $((0x10))
16
也可以指定 2 到 64 之间的任意进制,超过64进制则不支持.格式如下:
使用举例如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
xiaobaoqiu@xiaobaoqiu:~/myshell$ echo $((2#10))
2
xiaobaoqiu@xiaobaoqiu:~/myshell$ echo $((5#10))
5
xiaobaoqiu@xiaobaoqiu:~/myshell$ echo $((8#10))
8
xiaobaoqiu@xiaobaoqiu:~/myshell$ echo $((10#10))
10
xiaobaoqiu@xiaobaoqiu:~/myshell$ echo $((16#10))
16
xiaobaoqiu@xiaobaoqiu:~/myshell$ echo $((64#10))
64
xiaobaoqiu@xiaobaoqiu:~/myshell$ echo $((100#10))
bash: 100#10: 无效的算数进制 (错误符号是 "100#10")
2.2.bc
bc是一种任意精度运算语言,大多数 UNIX/Linux 安装程序都提供.因为它允许您指定输出进制,所以当您需要以十进制以外的进制输出时,这是一种很好的技术.
bc 的特殊变量 ibase 和 obase 分别包含用于输入和输出的进制的值.缺省情况下,都被设置为 10.要执行进制转换,需要改变其中的一个或两个值,然后提供一个数字.
1
2
3
4
5
6
xiaobaoqiu@xiaobaoqiu:~/myshell$ echo 'obase=16; 10' | bc
A
xiaobaoqiu@xiaobaoqiu:~/myshell$ echo 'obase=16; ibase=10; 10' | bc
A
xiaobaoqiu@xiaobaoqiu:~/myshell$ echo 'obase=10; ibase=16; 10' | bc
16
2.3.printf
格式化参数和C语言的格式一致:
1
2
3
4
xiaobaoqiu@xiaobaoqiu:~/myshell$ printf "%X\n" 100
64
xiaobaoqiu@xiaobaoqiu:~/myshell$ printf "%d\n" 0x10
16
2.自定义shell
自己写一个shell,处理多个输入,任意进制到任意进制的转换.通过这个脚本,学习了一下shell处理option的方式.
原理很简单,就是利用上面说道的bc命令.shell脚本如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#!/bin/bash
while getopts :i:o: opt
do
case "$opt" in
i) #输入的参数的进制
#echo "Found the -i option,with vale $OPTARG"
ibase=$OPTARG
;;
o) #输出参数进制
#echo "Found the -o option,with vale $OPTARG"
obase=$OPTARG
;;
*) #当有不认识的选项的时候arg为?
echo "unkonw argument, Usage : "
echo "$1 -i 10 -o 16 1 2 3 4 5 6 ..."
exit 1
esac
done
#跳过opt参数
shift $[$OPTIND - 1]
#参数检验
if [ ! $ibase ]; then
echo "Usage : $0 -i 10 -o 16 1 2 3 4 5 6 ..."
exit 1
fi
if [ ! $obase ]; then
echo "Usage : $0 -i 10 -o 16 1 2 3 4 5 6 ..."
exit 1
fi
echo "输入进制:$ibase"
echo "输出进制:$obase"
#执行进制转换
for i in $@
do
echo "obase=$obase; ibase=$ibase; $i" |bc
done
1.bc
2.bc
简单使用如下:
1
2
3
4
xiaobaoqiu@xiaobaoqiu:~/myshell$ ./trans -i 10 -o 16 100
输入进制:10
输出进制:16
64