(^o^)/~完美 发表于 2018-8-19 07:03:46

Shell笔记2——变量数值计算

  本文档主要讲解Shell变量的数值计算与实践
  基本大纲:
  1.算术运算符和命令介绍
  2.双小括号"(())"数值运算命令实践
  3.let运算命令的用法实践
  4.expr命令的用法实践
  5.bc命令的用法实践
  6.awk实现计算示例
  7.$[ ]符号的运算示例
  8.基于Shell变量输入read命令的运算实践
  一:算术运算符和命令介绍
  1、算术运算符
         算术运算符                   使用说明+、-加法(或正号)、减法(或负号)。*、/、%乘法、除法、取余。**幂运算。=比较符号(小于、小于等于、大于、大于等于) 向左移位,向右移位~、|、&、^按位取反、按位异或、按位与、按位或!、&&、||逻辑非(取反)、逻辑与(and)、逻辑或(or)==、!=、=比较符号(相等、不相等、相当于)。=、+=、-=、*=、/=、%=赋值运算符。例如a+=1等于a=a+1。++、--增加或减少、可前置也可放在变量结尾 *  2、算术运算命令
算术运算命令          使用说明(())用于整数运算的常用运算符,效率较高。let用于整数运算,类似于“(())”。expr可用于整数运算。bcLinux下的一个计算器程序(适合整数及小数运算)。$[]用于整数运算。awkawk既可以用于整数运算,也可以用于小数运算。declare  定义变量值和属性,-i参数可以用于定义整型变量,做运算
  二:双小括号"(())"数值运算命令实践
  1)简单的数值计算示例
  # echo $((1+1))
  2
  # echo $((6-3))
  3
  # ((i=5))
  # ((i=i*2))
  # echo $i
  10
  2)综合算术计算示例
  # ((a=1+2**3-4%3))
  # echo $a
  8
  # b=$((1+2**3-4%3))
  # echo $b
  8
  # echo $((1+2**3-4%3))
  8
  # a=$((100*(100+1)/2))
  # echo $a
  5050
  # echo $((100*(100+1)/2))
  5050
  3)特殊运算符号的运算示例
  # a=1
  # echo $((a=a+1))
  2
  # echo $((a+=1))
  3
  # echo $((a**2))
  9
  4)利用双括号进行比较和判断
  # echo $((35的结果是不成立的,因此输出0,0表示假
  0
  # echo $((8==8))
  1
  # if ((6>5&&5==5));then echo "yes";fi
  yes
  5)在变量前后使用--和++特殊运算符
  # a=6
  # echo $((a++))    #因为a在运算符++的前面,那么在输出整个表达式,会输出a的值,因为a为6,所有输出为6
  6
  # echo $a            #执行上面的表达式后,因为有a++,因此a会自增1,因此输出a的值为7
  7
  # a=6
  # echo $((a--))
  6
  # echo $a
  5
  # a=10
  # echo $a
  10
  # echo $((--a))    #因为a在运算符--的后面,那么在输出整个表达式,先进行自减 计算,因为a为10,自减1后为9,所以输出9
  9
  # echo $a            #执行上面的表达式后,a自减1,所有为9
  9
  # echo $((++a))
  10
  # echo $a
  10
  经验小结:
  变量a在运算符之前,输出的表达式的值为a本身,然后a自增或自减
  变量a在运算符之后,输出的表达式会先进行自增或自减, 表达式的值就是自增或自减后a的值
  6)通过“(())"运算后赋值给变量
  # b=99
  # echo $((b+1))
  100
  # echo $(( b+1   ))    #双小括号的两端有几个空格都无所谓,不限制格式
  100
  # b=$((b+1))      #将表达式的值赋值给变量
  # echo $b
  100
  7)各种"(())"运算的Shell脚本示例
  # cat test.sh
  #!/bin/bash
  a=10
  b=5
  echo "a-b=$(($a-$b))"
  echo "a+b=$(($a+$b))"
  echo "a*b=$(($a*$b))"
  echo "a/b=$(($a/$b))"
  echo "a**b=$(($a**$b))"
  echo "a%b=$(($a%$b))"
  # sh test.sh
  a-b=5
  a+b=15
  a*b=50
  a/b=2
  a**b=100000
  a%b=0
  三:let运算命令的用法实践
  let运算命令的语法格式为:let赋值表达式
  let赋值表达式的功能等同于“((赋值表达式))”
  # i=4
  # i=i+6
  # echo $i
  i+6
  # unset i
  # i=4
  # let i=i+6
  # echo $i
  10
  let i=i+6等价于((i=i+6))
  四:expr命令的用法实践
  expr命令用法: expr命令既可以用于整数运算,也可以用于相关字符串长度、匹配等的运算处理
  1)expr用于计算
  语法:expr Expression
  注意:运算符及用于计算的数字左右都至少有一个空格,否则会报错。
  使用乘号时,必须用反斜线屏蔽其特定含义,因为Shell可能会误解星号的含义。
  # expr 2 + 2
  4
  # expr 2 - 2
  0
  # expr 2 * 2
  expr: syntax error
  # expr 2 \* 2    #这个*号需要用\来转义
  4
  # expr 2 / 2
  1
  2)expr配合变量计算
  expr在Shell中可配合变量进行计算,但需要用反引号将计算表达式括起来
  # i=5
  # i=`expr $i + 5`
  # echo $i
  10
  3)expr判断一个变量值或字符串是否为整数
  # i=5
  # expr $i + 6 &>/dev/null   #把i和整数相加,&>/dev/null表示不保留任何输出
  # echo $?                               #输出返回值,返回0,则证明i的值为整数
  0
  # i=ywxi
  # expr $i + 6 &>/dev/null
  # echo $?                              #输出返回值,返回为非0,则证明i的值不为整数
  2
  结论:利用expr做计算,将一个未知的变量和一个已知的整数相加,看返回值是否为0,如果为0就可以判断出未知变量是整数,否则就不是整数
  4)expr match功能进行整数判断
  # expr match 1 *$
  1
  # expr match 564641 *$      #用正则匹配出符合要求的位数,大于0则为整数
  6
  # cat exprmatch.sh      #脚本测试
  #!/bin/bash
  if [[ `expr match "$1" *$` == 0 ]]
  then
  echo "$1 is not a num"
  else
  echo "$1 is a num"
  fi
  # sh exprmatch.sh 2      #为整数的输出
  2 is a num
  # sh exprmatch.sh dsa      #不为整数的输出
  dsa is not a num
  5)expr特殊用法:判断文件扩展命名是否符合要求
  # cat expr5.sh
  #!/bin/bash
  if expr "$1" : ".*\.txt" &>/dev/null
  then
  echo "you are using $1"
  else
  echo "please use *.txt file"
  fi
  # sh expr5.sh 1
  please use *.txt file
  # sh expr5.sh 1.txt
  you are using 1.txt
  # sed -n '10,20p' `which ssh-copy-id`      #expr命令实现系统ssh服务自带的ssh-copy-id公钥分布脚本示例如下
  if [ "-i" = "$1" ]; then
  shift

  # check if we have 2 parameters left, if so the first is the new>  if [ -n "$2" ]; then
  if expr "$1" : ".*\.pub" > /dev/null ; then

  >  else

  >  fi
  shift         # and this should leave $1 as the target name
  fi
  6)通过expr计算字符串的长度
  # char="I am ywxi"
  # expr length "$char"
  9
  # echo ${#char}      #常用的计算字符串长度方法
  9
  # echo ${char}|wc -L
  9
  # echo ${char}|awk '{print length($0)}'
  9
  五:bc命令的用法实践
  bc是类unix下的计算器,因此,除了可以作为计算机来使用,还可以作为命令行计算工具使用
  # bc      #执行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'.
  1+1
  2
  2*3+5
  11
  # echo 5+3|bc
  8
  # echo 5*3+5|bc
  20
  # echo "scale=2;5/3"|bc      #使用scale=2保留2位小数
  1.66
  # echo "scale=5;5/3"|bc      #使用scale=5保留5位小数
  1.66666
  重:多种运算法拓展实践,通过一条命令输出1+2+3+...+10的表达式,并计算出结果。
  打印表达式的命令如下:
  # seq -s "+" 10
  1+2+3+4+5+6+7+8+9+10
  # echo {1..10}|tr " " "+"
  1+2+3+4+5+6+7+8+9+10
  实现本题的多种方法:
  # echo `seq -s "+" 10`=`seq -s "+" 10|bc`      #使用bc计算,bc命令独有特点事除了支持证书运算之外,还支持小数运算
  1+2+3+4+5+6+7+8+9+10=55
  # echo "`seq -s '+' 10`="$((`seq -s "+" 10`))         #使用"(( ))"计算
  1+2+3+4+5+6+7+8+9+10=55
  # echo `seq -s '+' 10`=`seq -s " + " 10|xargs expr`      #使用expr计算,注意用于计算的数字左右都至少有一个空格,否则会报错
  1+2+3+4+5+6+7+8+9+10=55
  # echo `seq -s '+' 10`=$(echo $[`seq -s "+" 10`])         #使用$[ ]计算.
  1+2+3+4+5+6+7+8+9+10=55
  六:awk实现计算示例
  awk进行运算效果也很好,适合小数和整数,特别是命令行计算,尤其是小数,运算很精确,并且方便。
  # echo "6.6 3.3"|awk '{print ($1-$2)}'
  3.3
  # echo "6.6 3.3"|awk '{print ($1-2)/$2}'
  1.39394
  # echo "6.6 3.3"|awk '{print ($1+2)*$2}'
  28.38
  七:$[ ]符号的运算示例
  # i=5
  # i=$
  # echo $i
  8
  # i=$
  # echo $i
  6
  # echo $
  6
  # echo $
  8
  # echo $
  0
  # echo $
  2
  下面是解决问题的实例:打印杨辉三角
  # cat sanjiao.sh
  #!/bin/bash
  if (test -z $1) ;then
  read -p "Input Max Lines:" MAX
  else
  MAX=$1
  fi
  i=1
  while [ $i -le $MAX ]         #i行控制
  do
  j=1
  while [ $j -le $i ]            #j列控制
  do
  f=$      #f=i-1 这是另一种计算写法。
  g=$      #g=j-1 这是另一种计算写法。
  if [ $j -eq $i ] || [ $j -eq 1 ] ; then
  declare SUM_${i}_$j=1         #声明变量 头尾都是1
  else
  declare A=$       #取上一行的j列变量
  declare B=$       #取上一行的j-1列变量
  declare SUM_${i}_$j=`expr $A + $B`    #声明并计算当前变量的值
  fi
  echo -en $" "#输出当前变量
  let j++
  done
  echo   #换行
  let i++
  done
  八:基于Shell变量输入read命令的运算实践
  1)read命令
  语法格式:read 【参数】【变量名】
  常用参数: -p(prompt) :设置提示信息      -t(timeout):设置输入等待的时间,单位默认为秒
  read基本的读入功能示例:
  # read -t 5 -p "please input one num:" num      #-t设置等待时间,时间超过就退出了,一般不设置这个值
  please input one num:1
  # echo $num
  1
  # read -p "please input two number:" a b            #read的读入功能就相当于交互式接受用户输入,然后给变量赋值,体现了变量赋值灵活
  please input two number:2 3
  # echo $a
  2
  # echo $b
  3
  等价于echo -n "please input two number:" ;read a b
  2)read运用于脚本变量读取赋值示例:
  脚本1:
  # cat 3.sh
  #!/bin/bash
  echo -n "Enter your name:"   #参数-n的作用是不换行,echo默认是换行
  readname                   #从键盘输入
  echo "hello $name,welcome to my program"   #显示信息
  exit 0                     #退出shell程序。
  # sh 3.sh
  Enter your name:ywxi
  hello ywxi,welcome to my program
  脚本2:
  #该例子使用了-n选项,后接数值1个,指示read命令只要接受到一个字符就退出。只要按下一个字符进行回答,read命令立即接受输入并将其传给变量。无需按回车键。
  # cat 4.sh
  #!/bin/bash
  read -n1 -p "Do you want to continue : "answer
  case $answer in
  Y | y)
  echo -e"\nfine ,continue";;
  N | n)
  echo "ok,good bye";;
  *)
  echo "error choice";;
  esac
  exit 0
  # sh 4.sh
  Do you want to continue : Y
  fine ,continue
  # sh 4.sh
  Do you want to continue : y
  fine ,continue
  脚本3:
  #最后,还可以使用read命令读取Linux系统上的文件。每次调用read命令都会读取文件中的"一行"文本。当文件没有可读的行时,read命令将以非零状态退出。
  #读取文件的关键是如何将文本中的数据传送给read命令。
  #最常用的方法是对文件使用cat命令并通过管道将结果直接传送给包含read命令的while命令。
  # cat 5.sh
  #!/bin/bash
  count=1   #赋值语句,不加空格
  cat test | while read line      #cat 命令的输出作为read命令的输入,read读到的值放在line中
  do
  echo "Line $count:$line"
  count=$[ $count + 1 ]          #注意中括号中的空格。
  done
  echo "finish"
  exit 0
  # cat test
  read
  test
  ywxi
  # sh 5.sh
  Line 1:read
  Line 2:test
  Line 3:ywxi
  finish

页: [1]
查看完整版本: Shell笔记2——变量数值计算