zoukankan      html  css  js  c++  java
  • shell中的数学运算

    expr命令
    =======

    最开始,Bourne shell提供了一个特别的命令用来处理数学表达式。expr命令允许在命令行上处理数学表达式,但是特别笨拙:

    $ expr 1 + 5
    6

    expr命令能识别一些不同的数字和字符串操作符,如下表:

    =======================================================================
    操作符 描 述
    -----------------------------------------------------------------------
    ARG1 | ARG2 如果没有参数是null或0,返回ARG1;否则返回ARG2
    ARG1 & ARG2 如果没有参数是null或0,返回ARG1;否则返回0
    ARG1 < ARG2 如果ARG1小于ARG2,返回1;否则返回0
    ARG1 <= ARG2 如果ARG1小于或等于ARG2,返回1;否则返回0
    ARG1 = ARG2 如果ARG1等于ARG2,返回1;否则返回0
    ARG1 != ARG2 如果ARG1不等于ARG2,返回1;否则返回0
    ARG1 >= ARG2 如果ARG1大于或等于ARG2,返回1;否则返回0
    ARG1 > ARG2 如果ARG1大于ARG2,返回1;否则返回0
    ARG1 + ARG2 返回ARG1和ARG2的算术运算和
    ARG1 - ARG2 返回ARG1和ARG2的算术运算差
    ARG1 * ARG2 返回ARG1和ARG2的算术乘积
    ARG1 / ARG2 返回ARG1和ARG2的算术商
    ARG1 % ARG2 返回ARG1和ARG2的算术余数
    STR : EXP 如果EXP匹配到STR的某个模式,返回该模式匹配
    match STR EXP 如果EXP匹配到STR的某个模式,返回该模式匹配
    substr STR POS LEN 返回起始位置为POS(从1开始计数)、长度为LEN个字符的字符串
    index STR CHARS 返回在STR中找到CHARS字符串的位置;否则,返回0
    length STR 返回字符串STR的数值长度
    + TOKEN 将TOKEN解释成字符串,即使是个关键字
    (EXPRESSION) 返回EXPRESSION的值
    =======================================================================

    尽管标准操作符在expr命令中工作得很好,但在脚本或命令行上使用它们时仍有问题出现。许多expr命令操作符在shell中有其他意思(比如星号)。在expr命令中使用它们会得到一些诡异的结果:

    $ expr 5 * 2
    expr: syntax error
    $

    要解决这个问题,在传给expr命令前,你需要使用shell的转义字符(反斜线)来识别容易被shell错误解释的任意字符:

    $ expr 5 * 2
    10
    $

    不过,bash shell有一个针对处理数学运算符的改进,请看下面。

    使用方括号
    ========

    bash shell为了保持跟Bourne shell兼容而包含了expr命令,但它同样也提供了一个执行数学表达式更简单的方法。在bash shell中,在将一个数学运算结果赋给某个变量时,你可以用美元符和方括号($[ operation ])将数学表达式圈起来:

    $ var1=$[1 + 5]
    $ echo $var1
    6
    $ var2=$[$var1 * 2]
    $ echo $var2
    12
    $

    用方括号来执行shell数学运算比用expr命令方便很多,这种技术在shell脚本中也能工作。同样,在使用方括号来计算公式时,不用担心shell会误解乘号或其他符号。shell知道它不是通配符,因为它在方括号内。
    但是,bash shell数学运算只支持整数运算。如果要计算浮点,请往下看。

    浮点解决方案
    ==========

    有几种解决方案能够解决bash中数学运算的整数限制。最常见的解决方法是有内建的bash计算器,称作bc。

    ###bc的基本用法

    bash计算器其实是允许你在命令行输入浮点表达式、解释表达式、计算并返回结果的一种编程语言。bash计算器能够识别:

    - 数字(整数和浮点数)
    - 变量(简单变量和数组)
    - 注释(以#开始的行或者C语言中的/* */对)
    - 表达式
    - 编程语句(例如if-then)
    - 函数

    你可以在shell提示符下通过bc命令访问bash计算器:

    $ bc
    bc 1.06.95
    Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
    This is free software with ABSOLUTELY NO WARRANTY.
    For details type `warranty'.
    12*5.4
    64.8
    quit

    输入计算公式,bc会自动返回答案,退出输入quit。

    浮点运算是由一个内建的称为scale的变量控制的。你必须将这个值设置为结果是你想要的小数后的位数。

    bc 1.06.95
    Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
    This is free software with ABSOLUTELY NO WARRANTY.
    For details type `warranty'.
    3.44 /5
    0
    scale=4
    3.44 /5
    .6880
    quit

    ###在脚本中使用bc

    你可以使用反引号或者$()来运行bc命令并将输出赋给一个变量。基本格式是这样的:

    variable = `echo "options; expression" | bc`

    第一部分options允许你来设置变量。如果你需要设置不止一个变量,可以用分号来分开它们。expression变量定义了通过bc执行的数学表达式。例子:

    #!/bin/bash
    var1=`echo "scale=4; 3.44 / 5" | bc`
    echo The answer is $var1

    结果是: The answer is .6880

    这种方法适用于较短的运算,但有时你会更多地和你自己的数字打交道。如果你有很多运算,在同一个命令行中列出多个表达式就会有点麻烦。
    针对这个问题有个解决办法。bc命令能识别输入重定向,允许你将一个文件重定向到bc命令来处理。然后,这同样会叫要困惑,因为你必须将表达式存储到文件中。
    最好的办法是使用内联输入重定向,允许你直接在控制台重定向数据。在shell脚本中,你可以将输出赋给一个变量:

    variable=`bc << EOF
    options
    statements
    expressions
    EOF
    `

    EOF文件字符串标识了内联重定向数据的开始和结尾。记住仍然需要反引号来将bc命令的输出赋给变量。例如:

    #!/bin/bash

    var1=10.46
    var2=43.67
    var3=33.2
    var4=71

    var5=`bc << EOF
    scale = 4
    a1 = ($var1 * $var2)
    b1 = ($var3 * $var4)
    a1 + b1
    EOF
    `

    echo The final answer for this mass is $var5

  • 相关阅读:
    UVa 1349 (二分图最小权完美匹配) Optimal Bus Route Design
    UVa 1658 (拆点法 最小费用流) Admiral
    UVa 11082 (网络流建模) Matrix Decompressing
    UVa 753 (二分图最大匹配) A Plug for UNIX
    UVa 1451 (数形结合 单调栈) Average
    UVa 1471 (LIS变形) Defense Lines
    UVa 11572 (滑动窗口) Unique Snowflakes
    UVa 1606 (极角排序) Amphiphilic Carbon Molecules
    UVa 11054 Wine trading in Gergovia
    UVa 140 (枚举排列) Bandwidth
  • 原文地址:https://www.cnblogs.com/craftor/p/3811639.html
Copyright © 2011-2022 走看看