zoukankan      html  css  js  c++  java
  • Linux-shell-算术运算{expr、bc、dc、(( ))和[ ]}

    Linux-shell-算术运算{expr、bc、dc、(( ))和[ ]}

    摘自: https://www.cnblogs.com/snowsolf/p/3325235.html

    在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"
    ┌[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 stringstringposition $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 stringstringposition $length从1开始。

    3)index

    expr中的expr index stringsubstringstringsubstring索引命令功能在字符串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}进行计算,当然也可以expr中的expr lengthstring 求出字符串的长度。

    复制代码
    ┌[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
    复制代码

    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                   /*指定精度为5*/
    4/3
    1.33333
    ibase=2                    /*指定进制转换的输入机制为二进制,输出默认为是十进制*/
    1010
    10
    4^2                           /*指数运算,注:指数不能为浮点数*/
    16
    4*a(1)                        /*计算π值,a()是个函数:arctan(),好吧,老师教的都被狗吃了,π值是等于四倍的arctan(1)么?*/
    3.14159265358979323844
    quit                            /*退出*/
    复制代码

    2.4非交互模式

    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文档!

    3dc

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

    它也支持浮点运算。

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

    3.1交互模式

    复制代码
    ┌[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文档。

    3.2非交互模式

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

    ┌[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)。

    是不是很简单!

    4(( )) & [ ]

    这两个在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
    复制代码
    独行者如风!
     
    分类: Linux shell
  • 相关阅读:
    背水一战 Windows 10 (26)
    背水一战 Windows 10 (25)
    背水一战 Windows 10 (24)
    背水一战 Windows 10 (23)
    背水一战 Windows 10 (22)
    背水一战 Windows 10 (21)
    背水一战 Windows 10 (20)
    背水一战 Windows 10 (19)
    背水一战 Windows 10 (18)
    背水一战 Windows 10 (17)
  • 原文地址:https://www.cnblogs.com/LiuYanYGZ/p/9838231.html
Copyright © 2011-2022 走看看