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
  • 相关阅读:
    Go-常量-const
    centos-安装python3.6环境并配置虚拟环境
    centos-环境变量配置
    linux_命令格式和命令提示符
    linux_基础调优
    使用 Docker 容器应该避免的 10 个事情
    Linux--多网卡的7种Bond模式和交换机配置
    《Linux内核精髓:精通Linux内核必会的75个绝技》目录
    《Linux内核精髓:精通Linux内核必会的75个绝技》一HACK #21FUSE
    《Linux内核精髓:精通Linux内核必会的75个绝技》一HACK #20 使用fio进行I/O的基准测试
  • 原文地址:https://www.cnblogs.com/LiuYanYGZ/p/9838231.html
Copyright © 2011-2022 走看看