• Linux下计算命令: 求和、求平均值、求最值


    在Linux系统下,经常会有一些计算需求,那么下面就简单梳理下几个常用到的计算命令

    一、bc 命令
    bc命令是一种支持任意精度的交互执行的计算器语言。bash内置了对整数四则运算的支持,但是并不支持浮点运算,而bc命令可以很方便的进行浮点运算,当然整数运算也不再话下
    常用参数选项:
    -i:强制进入交互式模式;
    -l:定义使用的标准数学库;
    -w:对POSIX bc的扩展给出警告信息;
    -q:不打印正常的GNU bc环境信息;
    -v:显示指令版本信息;
    -h:显示指令的帮助信息。

    在bc工作环境下,可以使用以下计算符号:
    +    加法
    -     减法
    *    乘法
    /     除法
    ^    指数
    %   余数
    其中,在做“除法计算”或“余数计算”时,可以使用scale指定小数点之后的位数(默认为0,即整数)

    实例说明:

    [root@slave-server ~]# bc -v
    bc 1.06.95
    Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
    [root@slave-server ~]# bc <<< 5*4  
    20
    [root@slave-server ~]# bc <<< 5+4  
    9
    [root@slave-server ~]# bc <<< 50-14  
    36
    [root@slave-server ~]# bc <<< 50/10
    5
    [root@slave-server ~]# bc <<< 50/3
    16
    [root@slave-server ~]# bc <<< 3^3
    27
    

    如下,进入交互模式:也可以一行输入多个计算,用逗号;相隔。

    [root@slave-server ~]# 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'. 
    3+10
    13
    10-5
    5
    10*10
    100
    10^2
    100
    10/2
    5
    10/3
    3
    scale=4
    10/3
    3.3333
    10%3
    .0001
    3+4;5*2;5^2;18/4 
    7
    10
    25
    4.5000
    10^3;100+50;4000-598;33*8;899/34
    1000
    150
    3402
    264
    26.4411
    

    以上是使用交互的计算,也可以不进行交互而直接计算出结果。
    结合echo 和 "|" 符合
    [root@slave-server ~]# echo "(6+3)*2" |bc
    18
    [root@slave-server ~]# echo 15/4 |bc
    3
    [root@slave-server ~]# echo "scale=2;15/4" |bc
    3.75
    [root@slave-server ~]# echo "scale=2;100/30*100-98;20+45;90-70;15^2" |bc
    235.00
    65
    20
    225
    [root@slave-server ~]# echo "3+4;5*2;5^2;18/4" |bc
    7
    10
    25
    4
    bc除了scale来设定小数位之外,还有ibase和obase来其它进制的运算
    如下实例:
    将16进制的A7输出为10进制, 注意,英文只能大写
    [root@slave-server ~]# echo "ibase=16;A7" |bc
    167
    将2进制的11111111转成10进制
    [root@slave-server ~]# echo "ibase=2;11111111" |bc
    255
    输入为16进制,输出为2进制
    [root@slave-server ~]# echo "ibase=16;obase=2;B5-A4" |bc
    10001

    除此之外bc后可以接文件名(指定包含计算任务的文件)

    [root@slave-server ~]# cat calc.txt
    20+89
    56-17
    34*45
    30/8
    2^5
    scale=5
    100/3
    200%17
    [root@slave-server ~]# bc calc.txt
    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'. 
    109
    39
    1530
    3
    32
    33.33333
    .00010
    
    不打印正常的GNU信息
    [root@slave-server ~]# bc -q calc.txt
    109
    39
    1530
    3
    32
    33.33333
    .00010
    
    [root@slave-server ~]# bc -q < calc.txt
    109
    39
    1530
    3
    32
    33.33333
    .00010
    [root@slave-server ~]#

    也可以使用HERE 命令

    [root@slave-server ~]# bc << HERE 
    > 30+56
    > 30-14
    > 30*5
    > scale=3
    > 30/7
    > 10%3
    > 2^7
    HERE
    86
    16
    150
    4.285
    .001
    128
    

    可以使用内置的变量last引用上一次的结果

    [root@slave-server ~]# echo "50*4;last+100" | bc  
    200
    300
    

    last也可以用点号代替

    [root@slave-server ~]# echo "50*4;.+100" | bc  
    200
    300
    

    脚本模拟计算器

    [root@slave-server ~]# cat bc.sh 
    #!/bin/bash 
    bc << EOF  
    scale=2  
    $@  
    EOF
    [root@slave-server ~]# chmod 755 bc.sh
    [root@slave-server ~]# ./bc.sh 10*2
    20
    [root@slave-server ~]# ./bc.sh 10+32
    42
    [root@slave-server ~]# /bin/bash bc.sh 100/3
    33.33
    [root@slave-server ~]# /bin/bash -x bc.sh 100%13
    + bc
    .03
    

    二、expr 命令
    expr命令不光能计算加减乘除,还有很多表达式都可以计算出结果。
    不过有一点需要注意,在计算加减乘除时,不要忘了使用空格和转义。
    实例说明:

    [root@slave-server ~]#  expr 6 + 3                //注意中间都有空格
    9
    [root@slave-server ~]# expr 2 * 3                //注意乘法符号*前面有转义符号
    6
    [root@slave-server ~]# expr 14 % 9 
    5
    [root@slave-server ~]# a=3
    [root@slave-server ~]# expr $a + 5     //注意有变量,有空格
    8
    [root@slave-server ~]# a=`expr 4 + 2`
    [root@slave-server ~]# echo $a
    6
    

    expr对于字串的操作(计算)也很方便

    [root@slave-server ~]# expr length "yangzhigang.cublog.cn" 
    21

    从位置处抓取字串

    [root@slave-server ~]# expr substr "yangzhigang.cublog.cn" 1 11
    yangzhigang

    字串开始处

    [root@slave-server ~]# expr index "yangzhigang.cublog.cn" cu
    13

    三、echo命令
    echo用来进行回显,是周知的事。上面也配合bc来进行计算。其实echo也可以单独进行简单的计算

    [root@slave-server ~]# echo $((3+5))
    8
    [root@slave-server ~]# echo $(((3+5)*2))
    16
    

    echo还可以进行变量的计算

    [root@slave-server ~]# a=10
    [root@slave-server ~]# b=5
    [root@slave-server ~]# echo $(($a+$b))
    15
    [root@slave-server ~]# echo $a+$b
    10+5
    [root@slave-server ~]# echo $a+$b |bc
    15
    

    计算前天的日期

    [root@slave-server ~]# echo `date +%Y%m%d`
    20170204
    [root@slave-server ~]# echo `date +%Y%m%d`-2
    20170204-2
    [root@slave-server ~]# echo `date +%Y%m%d`-2 |bc
    20170202
    

    四、AWK命令
    awk在处理文件的时,可以进行运算,那当然也可以单单用来计算了

    [root@slave-server ~]# awk 'BEGIN{a=3+2;print a}'
    5
    [root@slave-server ~]# awk 'BEGIN{a=(3+2)*2;print a}'
    10
    [root@slave-server ~]# awk 'BEGIN{a=(3+2)*2;b=(5+8)*10/5;print a,b}'
    10 26
    [root@slave-server ~]# awk 'BEGIN{a=(3+2)*2;b=(5+8)*10/5;print 2a,3b}'
    210 326
    [root@slave-server ~]# awk 'BEGIN{a=(3+2)*2;b=(5+8)*10/5;c=5^2;print a,b,3c}'
    10 26 325
    

                                                                                                                                

    求和、平均值、最值
    [root@redis-server1 ~]# cat a
    1
    2
    3
    4
    5
    2333

    0) 求和
    [root@redis-server1 ~]# awk '{a+=$1}END{print a}' a
    2348

    1) 求最大值
    [root@redis-server1 ~]# awk '$0>a{a=$0}END{print a}' a
    2333

    2) 求最小值(思路:先定义一个最大值)
    [root@redis-server1 ~]# awk 'BEGIN{a=9999999}{if($1<a) a=$1 fi}END{print a}' a
    1

    3)求平均值
    第一种方法:在上面求和的基础上,除以参数个数
    [root@redis-server1 ~]# awk '{a+=$1}END{print a/NR}' a
    391.333

    第二种方法:写脚本
    [root@redis-server1 ~]# cat avg.sh

    #!/bin/bash
    let sum=0
    for num in $*;do
    let sum=$sum+$num
    done
    echo "scale=3;$sum/$#"|bc

    [root@redis-server1 ~]# chmod 755 avg.sh
    [root@redis-server1 ~]# ./avg.sh `cat a`
    391.333

    [root@redis-server1 ~]# ./avg.sh 40 45 60
    48.333
    .....................
    $? 上一个命令结果的返回值,0是正确,非0是错误的
    $0 当前程序名
    $n 命令行参数,比如$1是第一个参数,$2是第二个参数,$3是第三个参数.....
    $# 命令行参数的个数
    $* 格式形如$1 $2 $3 $4 ... $n
    $@ 格式形如"$1" "$2" "$3" "$4" ... "$n"

                                                         示例一                                                   
    [root@redis-server1 ~]# cat a.txt
    A 88
    B 78
    B 89
    C 44
    A 98
    C 433

    取得结果为:[root@redis-server1 ~]# cat a.txt|awk -F" " '{print $1}'|sort|uniq
    A
    B
    C

    第一种方法:
    [root@redis-server1 ~]# cat a.txt|awk -F" " '{print $1}'|sort|uniq
    A
    B
    C
    [root@redis-server1 ~]# for i in `cat a.txt|awk -F" " '{print $1}'|sort|uniq`;do cat a.txt|grep $i|xargs;done
    A 88 A 98
    B 78 B 89
    C 44 C 433
    [root@redis-server1 ~]# for i in `cat a.txt|awk -F" " '{print $1}'|sort|uniq`;do cat a.txt|grep $i|xargs;done|awk '{print $1,$2,$4}'
    A 88 98
    B 78 89
    C 44 433

    [root@redis-server1 ~]# for i in `cat a.txt|awk -F" " '{print $1}'|sort|uniq`;do cat a.txt|grep $i|xargs;done|awk -F" " '{print $1":",$2":",$4}'
    A: 88: 98
    B: 78: 89
    C: 44: 433

    第二种方法:
    [root@redis-server1 ~]# awk '{a[$1]=a[$1]" "$2}END{for(i in a)print i,a[i]}' a.txt |awk '{print $1":",$2";",$3}'
    A: 88; 98
    B: 78; 89
    C: 44; 433

                                                         示例二                                                  
    [root@redis-server1 ~]# cat b.txt
    123 444
    23 888
    455 45
    55 367
    66 100
    77 89

    对上面b.txt文件里的两列数字分别求和,求平均值
    [root@redis-server1 ~]# awk '{a+=$1;b+=$2}END{print a,b}' b.txt
    799 1933
    [root@redis-server1 ~]# awk '{a+=$1;b+=$2}END{print a":",b}' b.txt
    799: 1933
    [root@redis-server1 ~]# awk '{a+=$1;b+=$2}END{print a":"b}' b.txt
    799:1933

    [root@redis-server1 ~]# awk '{a+=$1;b+=$2}END{print a/NR,b/NR}' b.txt
    133.167 322.167
    [root@redis-server1 ~]# awk '{a+=$1;b+=$2}END{print a/NR":",b/NR}' b.txt
    133.167: 322.167
    [root@redis-server1 ~]# awk '{a+=$1;b+=$2}END{print a/NR":"b/NR}' b.txt
    133.167:322.167

                                     使用awk排除第一行和第二行的数据                                 

    如查看本机所有进程cpu的百分比总和
    [root@kevin ~]# ps auxw|awk '{print $3}'
    %CPU
    0.0
    0.0
    0.0
    0.0
    ....
    1.2
    0.0
    0.0
     
    [root@kevin ~]# ps auxw|awk '{print $3}'|wc -l
    145
     
    由于第一行有"%CPU",所以需要将结果中的第一行字符去掉
    [root@kevin ~]# ps auxw|awk '{if (NR>1){print $4}}'
    .....
    0.0
    0.0
    0.0
    0.0
    ....
    1.2
    0.0
    0.0
     
    [root@kevin ~]# ps auxw|awk '{if (NR>1){print $4}}'|wc -l
    144
     
    如果是去掉结果中的第一行,第二行和第三行,则只需要"NR>3"即可
    [root@kevin ~]# ps auxw|awk '{if (NR>2){print $4}}'

                                                    示例:条件判断                                            

    [root@master-node ~]# cat aa.txt
    123 root 
    345 wangshibo
    456 opt
    789 nginx
    100 wangshibo
    200 huanqiu
    300 hqtime
    
    打印aa.txt文件中第二列包含wang字符的内容
    [root@master-node ~]# awk '$2~/wang/ {print $0}' aa.txt
    345 wangshibo
    100 wangshibo
    
    打印aa.txt文件中第二列不包含wang字符的内容
    [root@master-node ~]# awk '$2 !~/wang/ {print $0}' aa.txt
    123 root 
    456 opt
    789 nginx
    200 huanqiu
    300 hqtime
    
    打印aa.txt文件中第二列以wang字符开头的内容
    [root@master-node ~]# awk '$2~/^wang/ {print $0}' aa.txt
    345 wangshibo
    100 wangshibo
    
    打印aa.txt文件中第二列以bo字符结尾的内容
    [root@master-node ~]# awk '$2~/bo$/ {print $0}' aa.txt
    345 wangshibo
    100 wangshibo
    
    打印aa.txt文件中第二列是wangshibo的内容(精确匹配)
    [root@master-node ~]# awk '$2=="wangshibo" {print $0}' aa.txt
    345 wangshibo
    100 wangshibo
    
    打印aa.txt文件中第二列不是wangshibo的内容
    [root@master-node ~]# awk '$2!="wangshibo" {print $0}' aa.txt
    123 root 
    456 opt
    789 nginx
    200 huanqiu
    300 hqtime
    
    打印aa.txt文件中第一列数字大于500的内容
    [root@master-node ~]# awk '$1>500 {print $0}' aa.txt
    789 nginx
    
    打印aa.txt文件中第一列数字大于500且第二列是wangshibo的内容
    [root@master-node ~]# awk '$1<200 && $2=="wangshibo" {print $0}' aa.txt
    100 wangshibo
    
    打印aa.txt文件中第一列数字大于500或是第二列是wangshibo的内容
    [root@master-node ~]# awk '$1<200 || $2=="wangshibo" {print $0}' aa.txt
    123 root 
    345 wangshibo
    100 wangshibo
    

                         示例:输入几个数,自动计算出最大值,最小值,总和                         

    [root@test2 ~]# cat test1.sh 
    #!/bin/bash
    #任意输入5个数,判断最大值,最小值,总和
    
    s=0
    read -p "please input:" num
    
    s=$(($s+$num))
    max=$num
    min=$num
    for i in `seq 4`
    do 
          read -p "please input:" num
          s=$(($s+$num))
          
          if [ $num -le $min ];then
            min=$num
          fi
    
          if [ $num -ge $max ];then
             max=$num
          fi
    
    done
    echo sum:$s max:$max min:$min
    
    [root@test2 ~]# /bin/bash test1.sh
    please input:12
    please input:13
    please input:14
    please input:15
    please input:16
    sum:70 max:16 min:12
    
    =================================================================================
    
    [root@test2 ~]# cat test2.sh 
    #!/bin/bash
    #任意输入3个数,判断最大值,最小值,总和
    
    s=0
    n=0
    for i in `seq 3`
    do 
          read -p "please input:" num
           expr  ${num}  +  0  1>/dev/null  2>&1  
           if   [   $?   -eq   0   ];then   
           echo   "${num}   is   a   number!"   
           else   
           echo   "${num}   is   not   a   number!"  
           exit 
            fi   
    
            
          s=$(($s+$num))
          [ $n -eq 0 ] && max=$num && min=$num
          n=$(($n+1))
           
          if [ $num -le $min ];then
            min=$num
          fi
    
          if [ $num -ge $max ];then
             max=$num
          fi
    
    done
    echo sum:$s max:$max min:$min n:$n
    
    [root@test2 ~]# /bin/bash test2.sh
    please input:123
    123   is   a   number!
    please input:567
    567   is   a   number!
    please input:512
    512   is   a   number!
    sum:1202 max:567 min:123 n:3
  • 相关阅读:
    autocomplete自动完成搜索提示仿google提示效果
    实现子元素相对于父元素左右居中
    javascript 事件知识集锦
    让 IE9 以下的浏览器支持 Media Queries
    「2013124」Cadence ic5141 installation on CentOS 5.5 x86_64 (limited to personal use)
    「2013420」SciPy, Numerical Python, matplotlib, Enthought Canopy Express
    「2013324」ClipSync, Youdao Note, GNote
    「2013124」XDMCP Configuration for Remote Access to Linux Desktop
    「2013115」Pomodoro, Convert Multiple CD ISO to One DVD ISO HowTo.
    「2013123」CentOS 5.5 x86_64 Installation and Configuration (for Univ. Labs)
  • 原文地址:https://www.cnblogs.com/kevingrace/p/6364307.html
Copyright © 2020-2023  润新知