Shell数学运算
1. 常用的数学运算工具及表达式
1.1 $[ expression ]表达式
-
-
$[...]表达式中变量符号$可有可无,表达式各参数之间空格可有可无。支持+,-,*,/,%, ++,--,>,<,==,**,&&,||等运算符。如
a=8;echo $[$a+8]等同于echo $[ a + 8 ],$和空格可有可无。
更多示例如下:
-
-
- 注意和
[ expressions ]表达式做区分,[]是test的用法变体,在[]表达式中变量必须带$,各参数之间必须有空格,数值比较必须用lt,le,gt,ge,eq,ne参数,如用<>=符号,则视为字符串比较。
- 注意和
1.2 $(( expressions )) 表达式
$(( expressions ))除了具备 $[ expression ]的运算符支持的能力外,还支持多个表达式运算,进制转换。
- 支持多个表达式运算, 表达式之间用“,”分隔。
- 转换成10进制输出
- 类C语言风格的for循环
1.3 expr
expr工具可以用来进行整数数值运算和数值比较,需注意以下几点:
- 只能对整数参数进行运算和比较
- 参数之间必须有空格
- 对于通配符如*,必须要转义
- 变量必须使用$来引用
用法如下:
- 整数数学运算和逻辑判断
- 判断变量是否为整数
由于expr只能对整数进行数学运算,所以可以通过expr命令的退出码来判断是变量是否为整数
1.4 let
let是shell内置命令,常用于整数的整值运算,使用时需要注意
let只接受整数数值运算,传入变量为字符串会默认变量值为0. (实际测试还会出现未知的异常错误)let运算=号左右两边不能有空格, 除非let 的表达式用双引号引起来(建议)let等式中的变量可以不用带$, 对于*,()符号可以不用转义。
用法:
在循环中使用let计数:
1.5 bc
bc计算器,不仅可以进行整数计算,还支持对浮点数的运算,进制转换,幂运算。
- 整数计算,逻辑判断
- 浮点数计算
注意:bc变量scale设置的小数位只对除法有效,加减乘法还是输出最高精度,想要保留具体小数点位数建议还是使用printf格式化打印
- 进制转换
- 科学计算,利用bc -l 使用数学库来实现求幂运算,正弦,余弦,正切等
- 批量运算
1.6 awk/gawk
awk是一款非常强大的文本处理工作,涉及大量的文本处理工作时选择awk无疑是高效的,awk使用方法网上有大量的介绍。本章节重点使用awk来进行数学运算。
awk/gawk已经可以作为一门编程语言,在数学运算上参照C语言编程规范, 支持
- 算术运算:
+,-,*,/,%,++,-- - 关系运算:
> ,<,==,<=,>=,!= - 逻辑运算:
&&,||,! - 赋值运算:
=,+=,-=,*=,/=,%=, &=,^=,|= - 三元运算:
?: - 位运算函数:
lshift(var,count),rshift(var,count), or(var1,var2), xor(var1,var2), and(var1,var2),compl(var) - 内置数学函数:
sin(var),cos(var),exp(var),sqrt(var),log(var),等等 更为关键的是,awk/awk还可以自定义算法函数, 可以处理更为复杂的逻辑运算。
用法
2. Shell数学运算实践
本节参考一段C语言代码,获取字符串的hash值,把C语言代码转换成Bash语言和awk,来练习之前章节所学习的一些技能。
2.1 C语言Hash算法
以下C语言代码中ELFHash函数来源于http://www.partow.net/programming/hashfunctions
test@test-PC:~/work/study/cplus$ vi hash.c
编译执行,结果如下:
2.2 Bash语言Hash算法
test@test-PC:~/work/study/cplus$ vi hash.sh
执行结果如下:
2.3 awk语言Hash算法
test@test-PC:~/work/study/cplus$ vi hash.awk
执行结果如下:
