在Linux下作算术运算时你是如何进行的呢?是否是还在用expr呢?你会说我还会bc还有其它的呢!正则表达式
闲话很少扯,干正事!shell
expr在使用中要注意一些书写,如表达式中量和运算符号之间的空格及一些运算符号须要转义,还有一点须要记住,expr只适用于整数之间的运算!函数
expr的help文档中关于表达式部分以下:ui
ARG1 | ARG2 若ARG1 的值不为0 或者为空,则返回ARG1,不然返回ARG2 ARG1 & ARG2 若两边的值都不为0 或为空,则返回ARG1,不然返回 0 ARG1 < ARG2 ARG1 小于ARG2 ARG1 <= ARG2 ARG1 小于或等于ARG2 ARG1 = ARG2 ARG1 等于ARG2 ARG1 != ARG2 ARG1 不等于ARG2 ARG1 >= ARG2 ARG1 大于或等于ARG2 ARG1 > ARG2 ARG1 大于ARG2 ARG1 + ARG2 计算 ARG1 与ARG2 相加之和 ARG1 - ARG2 计算 ARG1 与ARG2 相减之差 ARG1 * ARG2 计算 ARG1 与ARG2 相乘之积 ARG1 / ARG2 计算 ARG1 与ARG2 相除之商 ARG1 % ARG2 计算 ARG1 与ARG2 相除之余数
这一部分相信你们用的最多,也对这些比较了解了,下面咱们用一个表达式来讲明:spa
$expr 9 + 8 - 7 \* 6 / 5 + \( 4 - 3 \) \* 2 11
经过结果相信你已知道expr的计算规律,它与咱们平常所理解的数学表达式同样,括号的优先级最高,而后是“*”、“/”,并且每一个数或符号都须要用空格分隔,结果也是整数。命令行
expr还能够对字符串进行操做:code
match 字符串 表达式等于"字符串 :表达式" substr 字符串 偏移量 长度替换字符串的子串,偏移的数值从 1 起计 index 字符串 字符在字符串中发现字符的地方创建下标,或者标0 length 字符串字符串的长度
1)matchblog
expr中的expr match $string substring命令在string字符串中匹配substring字符串(substring字符串能够是正则表达式),而后返回匹配到的substring字符串的长度,若找不到则返回0。索引
下面咱们来个实例:文档
┌[2013-08-24/7.18 15:00:01] ├[14+1][~] └[snowsolf@Ubuntu-LTS-1 ╰_╯]$str="123 456 789" ┌[2013-08-24/7.18 15:00:30] ├[14+1][~] └[snowsolf@Ubuntu-LTS-1 ╰_╯]$expr match "$str" .*5 6
.*5匹配了6个字符。
2)substr
在shell中能够用{string:position}和{string:position:length}进行对string字符串中字符的抽取。第一种是从position位置开始抽取直到字符串结束,第二种是从position位置开始抽取长度为length的子串。而用expr中的expr substr $string $position $length一样能实现上述功能。
实例:
┌[2013-08-24/7.18 15:19:17] ├[14+1][~] └[snowsolf@Ubuntu-LTS-1 ╰_╯]$str="123 456 789" ┌[2013-08-24/7.18 15:19:31] ├[14+1][~] └[snowsolf@Ubuntu-LTS-1 ╰_╯]$echo ${str:5} 56 789 ┌[2013-08-24/7.18 15:19:59] ├[14+1][~] └[snowsolf@Ubuntu-LTS-1 ╰_╯]$echo ${str:5:3} 56 ┌[2013-08-24/7.18 15:20:07] ├[14+1][~] └[snowsolf@Ubuntu-LTS-1 ╰_╯]$expr substr "$str" 5 3 456
从中能够看出{string:position}和{string:position:length}从0开始计数,而expr substr $string $position $length从1开始。
3)index
expr中的expr index $string substring索引命令功能在字符串$string上找出substring中字符第一次出现的位置,若找不到则expr index返回0。注意它匹配的是字符而非字符串。
实例:
┌[2013-08-24/7.18 15:35:19] ├[14+1][~] └[snowsolf@Ubuntu-LTS-1 ╰_╯]$str="123 456 789" ┌[2013-08-24/7.18 15:37:02] ├[14+1][~] └[snowsolf@Ubuntu-LTS-1 ╰_╯]$expr index "$str" b 0 ┌[2013-08-24/7.18 15:37:08] ├[14+1][~] └[snowsolf@Ubuntu-LTS-1 ╰_╯]$expr index "$str" 9 11
4)length
计算字符串的长度。咱们能够用awk中的length(s)进行计算。咱们也能够用echo中的echo ${#string}进行计算,固然也能够expr中的expr length $string 求出字符串的长度。
┌[2013-08-24/7.18 15:39:39] ├[14+1][~] └[snowsolf@Ubuntu-LTS-1 ╰_╯]$str="123 456 789" ┌[2013-08-24/7.18 15:39:52] ├[14+1][~] └[snowsolf@Ubuntu-LTS-1 ╰_╯]$echo ${#str} 11 ┌[2013-08-24/7.18 15:39:57] ├[14+1][~] └[snowsolf@Ubuntu-LTS-1 ╰_╯]$expr length "$str" 11
重点来了!
bc是一种任意精度的计算语言,注意是一种语言,它提供了一些语法结构,好比条件判断、循环等,能够说是很强大的,可是我在实际中尚未找到须要这个用途的场合 。另一个用途就是用来进行进制转换。
上面咱们介绍的expr之支持整数运算,但对于浮点运算就无能为力了,并且expr不能进行指数运算,而都有bc这些都再也不话下。
咱们先来了解几个有用的参数:
-i 强制交互模式; -l 使用bc的内置库,bc里有一些数学库,对三角计算等很是实用; -q 进入bc交互模式时再也不输出版本等多余的信息。
ibase,obase 用于进制转换,ibase是输入的进制,obase是输出的进制,默认是十进制;
scale 小数保留位数,默认保留0位。
在shell命令行直接输入bc及能进入bc语言的交互模式。
$bc -l -q 4/3 /*未指定精度默认保留整数*/ 1 scale=5 /*指定精度为5*/ 4/3 1.33333 ibase=2 /*指定进制转换的输入机制为二进制,输出默认为是十进制*/ 1010 10 4^2 /*指数运算,注:指数不能为浮点数*/ 16 4*a(1) /*计算π值,a()是个函数:arctan(),好吧,老师教的都被狗吃了,π值是等于四倍的arctan(1)么?*/ 3.14159265358979323844 quit /*退出*/
bc也能够进行非交互式的运算,方法是与echo一块儿使用。
┌[2013-08-24/7.18 18:42:27] ├[14+1][~] └[snowsolf@Ubuntu-LTS-1 ╰_╯]$echo "scale=5;9+8-7*6/5^2"|bc /*优先级^ > *、/ > +、- */ 15.32000 ┌[2013-08-24/7.18 18:45:35] ├[14+1][~] └[snowsolf@Ubuntu-LTS-1 ╰_╯]$echo "s(2/3*a(1))"|bc -l /*还记得sina(30°)等于0.5么?皇上! ^_^*/ .49999999999999999998 ┌[2013-08-24/7.18 18:49:13] ├[14+1][~] └[snowsolf@Ubuntu-LTS-1 ╰_╯]$echo "scale=5;sqrt(15)"|bc /*开方*/ 3.87298 ┌[2013-08-24/7.18 18:49:18] ├[14+1][~] └[snowsolf@Ubuntu-LTS-1 ╰_╯]$echo "ibase=16;obase=2;ABC"|bc 101010111100
更多参考man文档!
可能你曾经知道有此命令,也可能你还不知道。dc相比与bc要复杂,可是简单操做仍是比较简单。简单的说dc是一直压栈操做,和bc同样,它也能够交互使用,或者与echo一块儿配合使用。
它也支持浮点运算。
可是如今我尚未想到这种压栈式算术运算有什么有点。
┌[2013-09-16/8.12 20:33:53] ├[7+10][~/shell] └[snowsolf@Ubuntu-LTS-1 ╰_╯]$dc 2 3- p /*输出(3 - 2)*/ -1 4 * p /*输出(-1 * 4)*/ -4 2 / p /*输出(-4 / 2)*/ -2 3.4 + p /*输出(-2 + 3.4)*/ 1.4 4 d /*复制栈顶值*/ * p /*输出(4 * 4)*/ 16 q /*退出*/
还有其余命令如:
c 清除压栈
d 复制栈顶的值
p 输出栈顶值
q 退出交互模式
还有其它能够参考对应man文档。
一个算式让你就看的差很少了。
┌[2013-09-16/8.12 20:47:43] ├[7+10][~/shell] └[snowsolf@Ubuntu-LTS-1 ╰_╯]$echo "4 3 * 2 + 1 -p"|dc 13
算式是:(4 * 3 + 2 - 1)。
是否是很简单!
这两个在shell中比较常见,这两个和expr命令有些相似,也是用于整数计算。
他们支持的运算符号有以下:
| 位或 + || 若先后二者都不为0,则返回1,不然返回0 & 位与 + && 若前者为0,再也不对后者进行处理,不然对后者处理,后者不为0时返回1 < <= == != >= > + - * / %
带+号的两个运算符实际上是shell支持的运算符。
这两个对与expr的优势是:运算符号所有不须要转义。
咱们一味的在shell中用那些别人没用过的命令来作同一件事,但不要忘了(( ))和[ ]是shell中常见的,并且很是实用,但并不是是你经常使用的!
实例:
┌[2013-09-16/8.12 20:47:51] ├[7+10][~/shell] └[snowsolf@Ubuntu-LTS-1 ╰_╯]$echo $(( 2 + 5 )) 7 ┌[2013-09-16/8.12 21:11:14] ├[7+10][~/shell] └[snowsolf@Ubuntu-LTS-1 ╰_╯]$echo $(( 2 * 5 )) 10 ┌[2013-09-16/8.12 21:11:19] ├[7+10][~/shell] └[snowsolf@Ubuntu-LTS-1 ╰_╯]$echo $(( 2 - 5 )) -3 ┌[2013-09-16/8.12 21:11:23] ├[7+10][~/shell] └[snowsolf@Ubuntu-LTS-1 ╰_╯]$echo $(( 2 % 5 )) 2 ┌[2013-09-16/8.12 21:11:29] ├[7+10][~/shell] └[snowsolf@Ubuntu-LTS-1 ╰_╯]$echo $[ 2 % 5 ] 2 ┌[2013-09-16/8.12 21:11:45] ├[7+10][~/shell] └[snowsolf@Ubuntu-LTS-1 ╰_╯]$echo $[ 2 - 5 ] -3 ┌[2013-09-16/8.12 21:11:50] ├[7+10][~/shell] └[snowsolf@Ubuntu-LTS-1 ╰_╯]$echo $[ 2 * 5 ] 10 ┌[2013-09-16/8.12 21:11:55] ├[7+10][~/shell] └[snowsolf@Ubuntu-LTS-1 ╰_╯]$echo $[ 2 + 5 ] 7