[shell]算术运算

在Linux下做算术运算时你是如何进行的呢?是不是还在用expr呢?你会说我还会bc还有其它的呢!

闲话不多扯,干正事!

1expr

expr在使用中要注意一些书写,如表达式中量和运算符号之间的空格及一些运算符号需要转义,还有一点需要记住,expr只适用于整数之间的运算!

1.1表达式

expr的help文档中关于表达式部分如下:

  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 相除之余数

这一部分相信大家用的最多,也对这些比较了解了,下面我们用一个表达式来说明:

$expr 9 + 8 - 7 \* 6 / 5 + \( 4 - 3 \) \* 2
11

通过结果相信你已知道expr的计算规律,它与我们日常所理解的数学表达式一样,括号的优先级最高,然后是“*”、“/”,而且每个数或符号都需要用空格分隔,结果也是整数。

1.2字符串

expr还可以对字符串进行操作:

  match 字符串 表达式等于"字符串 :表达式"
  substr 字符串 偏移量 长度替换字符串的子串,偏移的数值从 1 起计
  index 字符串 字符在字符串中发现字符的地方建立下标,或者标0
  length 字符串字符串的长度

1)match

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"
┌[30]
├[1 ╰_╯]$expr match $str" .*5
6

.*5匹配了6个字符。

2)substr

在shell中可以用{string:position}和{string:position:length}进行对string字符串中字符的抽取。第一种是从position位置开始抽取直到字符串结束,第二种是从position位置开始抽取长度为length的子串。而用expr中的expr substr string stringposition $length同样能实现上述功能

实例:

19:17] ├[31] ├[echo ${str:5} 56 789 ┌[59] ├[5:3} 56 ┌[20:07] ├[expr substr " 5 3 456

从中可以看出{string:position}和{string:position:length}从0开始计数,而expr substr string stringposition $length从1开始。

3)index

expr中的expr index stringsubstring@H_404_375@ stringsubstring索引命令功能在字符串string上找出substring中字符第一次出现的位置,若找不到则expr index返回0。注意它匹配的是字符而非字符串。

35:19] ├[37:02] ├[expr index " b 0 ┌[08] ├[9 11

4)length

计算字符串的长度。我们可以用awk中的length(s)进行计算。我们也可以用echo中的echo{#string}进行计算,当然也可以expr中的exprlength{#string}进行计算,当然也可以expr中的exprlengthstring 求出字符串的长度。

┌[39:39]
├[52]
├[echo ${#str}
11
┌[57]
├[expr length "
11

2bc

重点来了!

bc是一种任意精度的计算语言,注意是一种语言,它提供了一些语法结构,比如条件判断、循环等,可以说是很强大的,但是我在实际中还没有找到需要这个用途的场合。另外一个用途就是用来进行进制转换。

上面我们介绍的expr之支持整数运算,但对于浮点运算就无能为力了,而且expr不能进行指数运算,而都有bc这些都不再话下。

2.1参数

我们先来了解几个有用的参数:

-i 强制交互模式;

-l 使用bc的内置库,bc里有一些数学库,对三角计算等非常实用;

-q 进入bc交互模式时不再输出版本等多余的信息。

2.2特殊变量

ibase,obase 用于进制转换,ibase是输入的进制,obase是输出的进制,默认是十进制;

scale 小数保留位数,默认保留0位。

2.3交互模式

在shell命令行直接输入bc及能进入bc语言的交互模式。

$bc -l -q
4/3                           /*未指定精度默认保留整数*/
1
scale=5                   指定精度为51.33333
ibase=2                    指定进制转换的输入机制为二进制,输出默认为是十进制1010
10
4^2                           指数运算,注:指数不能为浮点数16
4*a(1)                        计算π值,a()是个函数:arctan(),好吧,老师教的都被狗吃了,π值是等于四倍的arctan(1)么?3.14159265358979323844
quit                            退出*/

2.4非交互模式

bc也可以进行非交互式的运算,方法是与echo一起使用。

18:42:27] ├[echo scale=5;9+8-7*6/5^2"|bc 优先级^ > *、/ > +、- 15.32000 ┌[45:35] ├[s(2/3*a(1))"|bc -l 还记得sina(30°)等于0.5么?皇上! ^_^*/ .49999999999999999998 ┌[49:13] ├[scale=5;sqrt(15)"|bc 开方3.87298 ┌[18] ├[ibase=16;obase=2;ABC"|bc 101010111100

更多参考man文档!

3dc

可能你曾经知道有此命令,也可能你还不知道。dc相比与bc要复杂,但是简单操作还是比较简单。简单的说dc是一直压栈操作,和bc一样,它也可以交互使用,或者与echo一起配合使用。

它也支持浮点运算。

但是现在我还没有想到这种压栈式算术运算有什么有点。

3.1交互模式

09-16/8.12 33:53] ├[7+10][~/shell] └[snowsolf@Ubuntu-LTS-1 ╰_╯]$dc 3- p 输出(3 - 2)*/ -1 4 * p 输出(-1 * 4)4 2 / p 输出(-4 / 2)3.4 + p 输出(-2 + 3.4)1.4 4 d 复制栈顶值*/ * p 输出(4 * 4)*/ 16 q /*退出*/

还有其他命令如:

c           清除压栈

d           复制栈顶的值

p           输出栈顶值

q           退出交互模式

还有其它可以参考对应man文档。

3.2非交互模式

一个算式让你就看的差不多了。

┌[47:43]
├[4 3 * 2 + 1 -p"|dc
13

算式是:(4 * 3 + 2 - 1)。

是不是很简单!

4(( )) & [ ]

这两个在shell中比较常见,这两个和expr命令有些类似,也是用于整数计算。

他们支持的运算符号有如下:

 |    位或
+ ||   若前后两者都不为0,则返回1,否则返回0
 &  位与
+ &&  若前者为0,不再对后者进行处理,否则对后者处理,后者不为0时返回1
 < 
 <=
 ==
 !=
 >=
 > 
 + 
 - 
 * 
 / 
 % 

带+号的两个运算符其实是shell支持的运算符。

这两个对与expr的优点是:运算符号全部不需要转义。

我们一味的在shell中用那些别人没用过的命令来做同一件事,但不要忘了(( ))和[ ]是shell中常见的,而且非常实用,但并非是你常用的!

实例:

51] ├[echo $(( 2 + 5 )) 7 ┌[21:11:14] ├[2 * 10 ┌[2 - 5 )) -3 ┌[23] ├[2 % 2 ┌[29] ├[echo $[ 5 ] 45] ├[5 ] -50] ├[55] ├[7

相关文章

普通模式 >G 增加当前行到文档末尾处的缩紧层级 $ 移动到本行的末尾 . 相当于一个...
原文连接: https://spacevim.org/cn/layers/lang/elixir/ 模块简介 功能特性 启用模块 快捷键 语言专属...
原文连接: https://spacevim.org/cn/layers/lang/dart/ 模块简介 功能特性 依赖安装及启用模块 启用模...
 =   赋值操作符,可以用于算术和字符串赋值 +        加法计算     -        减法运算...
1.根据包名来查看指定的APP指定数据 adb shell "top | grep com.xxx.xxx" 由于这样打印出来的数...
ctrl+F 向下翻页 ctrl+B 向下翻页 u 取消最近一次操作 U 取消当前行的操作 ZZ 保存当前内容并退出 gg 跳...