本文档主要讲解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 | 可用于整数运算。 |
bc | Linux下的一个计算器程序(适合整数及小数运算)。 |
$[] | 用于整数运算。 |
awk | awk既可以用于整数运算,也可以用于小数运算。 |
declare | 定义变量值和属性,-i参数可以用于定义整型变量,做运算 |
二:双小括号"(())"数值运算命令实践
1)简单的数值计算示例
[root@localhost practice]# echo $((1+1))
2
[root@localhost practice]# echo $((6-3))
3
[root@localhost practice]# ((i=5))
[root@localhost practice]# ((i=i*2))
[root@localhost practice]# echo $i
10
2)综合算术计算示例
[root@localhost practice]# ((a=1+2**3-4%3))
[root@localhost practice]# echo $a
8
[root@localhost practice]# b=$((1+2**3-4%3))
[root@localhost practice]# echo $b
8
[root@localhost practice]# echo $((1+2**3-4%3))
8
[root@localhost practice]# a=$((100*(100+1)/2))
[root@localhost practice]# echo $a
5050
[root@localhost practice]# echo $((100*(100+1)/2))
5050
3)特殊运算符号的运算示例
[root@localhost practice]# a=1
[root@localhost practice]# echo $((a=a+1))
2
[root@localhost practice]# echo $((a+=1))
3
[root@localhost practice]# echo $((a**2))
9
4)利用双括号进行比较和判断
[root@localhost practice]# echo $((3<5)) #3<5的结果是成立的,因此输出1,1表示真
1
[root@localhost practice]# echo $((3>5)) #3>5的结果是不成立的,因此输出0,0表示假
0
[root@localhost practice]# echo $((8==8))
1
[root@localhost practice]# if ((6>5&&5==5));then echo "yes";fi
yes
5)在变量前后使用--和++特殊运算符
[root@localhost practice]# a=6
[root@localhost practice]# echo $((a++)) #因为a在运算符++的前面,那么在输出整个表达式,会输出a的值,因为a为6,所有输出为6
6
[root@localhost practice]# echo $a #执行上面的表达式后,因为有a++,因此a会自增1,因此输出a的值为7
7
[root@localhost practice]# a=6
[root@localhost practice]# echo $((a--))
6
[root@localhost practice]# echo $a
5
[root@localhost practice]# a=10
[root@localhost practice]# echo $a
10
[root@localhost practice]# echo $((--a)) #因为a在运算符--的后面,那么在输出整个表达式,先进行自减 计算,因为a为10,自减1后为9,所以输出9
9
[root@localhost practice]# echo $a #执行上面的表达式后,a自减1,所有为9
9
[root@localhost practice]# echo $((++a))
10
[root@localhost practice]# echo $a
10
经验小结:
变量a在运算符之前,输出的表达式的值为a本身,然后a自增或自减
变量a在运算符之后,输出的表达式会先进行自增或自减, 表达式的值就是自增或自减后a的值
6)通过“(())"运算后赋值给变量
[root@localhost practice]# b=99
[root@localhost practice]# echo $((b+1))
100
[root@localhost practice]# echo $(( b + 1 )) #双小括号的两端有几个空格都无所谓,不限制格式
100
[root@localhost practice]# b=$((b+1)) #将表达式的值赋值给变量
[root@localhost practice]# echo $b
100
7)各种"(())"运算的Shell脚本示例
[root@localhost practice]# 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))"
[root@localhost practice]# 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赋值表达式的功能等同于“((赋值表达式))”
[root@localhost practice]# i=4
[root@localhost practice]# i=i+6
[root@localhost practice]# echo $i
i+6
[root@localhost practice]# unset i
[root@localhost practice]# i=4
[root@localhost practice]# let i=i+6
[root@localhost practice]# echo $i
10
let i=i+6等价于((i=i+6))
四:expr命令的用法实践
expr命令用法: expr命令既可以用于整数运算,也可以用于相关字符串长度、匹配等的运算处理
1)expr用于计算
语法:expr Expression
注意:运算符及用于计算的数字左右都至少有一个空格,否则会报错。
使用乘号时,必须用反斜线屏蔽其特定含义,因为Shell可能会误解星号的含义。
[root@localhost practice]# expr 2 + 2
4
[root@localhost practice]# expr 2 - 2
0
[root@localhost practice]# expr 2 * 2
expr: syntax error
[root@localhost practice]# expr 2 \* 2 #这个*号需要用\来转义
4
[root@localhost practice]# expr 2 / 2
1
2)expr配合变量计算
expr在Shell中可配合变量进行计算,但需要用反引号将计算表达式括起来
[root@localhost practice]# i=5
[root@localhost practice]# i=`expr $i + 5`
[root@localhost practice]# echo $i
10
3)expr判断一个变量值或字符串是否为整数
[root@localhost practice]# i=5
[root@localhost practice]# expr $i + 6 &>/dev/null #把i和整数相加,&>/dev/null表示不保留任何输出
[root@localhost practice]# echo $? #输出返回值,返回0,则证明i的值为整数
0
[root@localhost practice]# i=ywxi
[root@localhost practice]# expr $i + 6 &>/dev/null
[root@localhost practice]# echo $? #输出返回值,返回为非0,则证明i的值不为整数
2
结论:利用expr做计算,将一个未知的变量和一个已知的整数相加,看返回值是否为0,如果为0就可以判断出未知变量是整数,否则就不是整数
4)expr match功能进行整数判断
[root@localhost practice]# expr match 1 [0-9][0-9]*$
1
[root@localhost practice]# expr match 564641 [0-9][0-9]*$ #用正则匹配出符合要求的位数,大于0则为整数
6
[root@localhost practice]# cat exprmatch.sh #脚本测试
#!/bin/bash
if [[ `expr match "$1" [0-9][0-9]*$` == 0 ]]
then
echo "$1 is not a num"
else
echo "$1 is a num"
fi
[root@localhost practice]# sh exprmatch.sh 2 #为整数的输出
2 is a num
[root@localhost practice]# sh exprmatch.sh dsa #不为整数的输出
dsa is not a num
5)expr特殊用法:判断文件扩展命名是否符合要求
[root@localhost practice]# cat expr5.sh
#!/bin/bash
if expr "$1" : ".*\.txt" &>/dev/null
then
echo "you are using $1"
else
echo "please use *.txt file"
fi
[root@localhost practice]# sh expr5.sh 1
please use *.txt file
[root@localhost practice]# sh expr5.sh 1.txt
you are using 1.txt
[root@localhost practice]# 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 ID file
if [ -n "$2" ]; then
if expr "$1" : ".*\.pub" > /dev/null ; then
ID_FILE="$1"
else
ID_FILE="$1.pub"
fi
shift # and this should leave $1 as the target name
fi
6)通过expr计算字符串的长度
[root@localhost practice]# char="I am ywxi"
[root@localhost practice]# expr length "$char"
9
[root@localhost practice]# echo ${#char} #常用的计算字符串长度方法
9
[root@localhost practice]# echo ${char}|wc -L
9
[root@localhost practice]# echo ${char}|awk '{print length($0)}'
9
五:bc命令的用法实践
bc是类unix下的计算器,因此,除了可以作为计算机来使用,还可以作为命令行计算工具使用
[root@localhost practice]# 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
[root@localhost practice]# echo 5+3|bc
8
[root@localhost practice]# echo 5*3+5|bc
20
[root@localhost practice]# echo "scale=2;5/3"|bc #使用scale=2保留2位小数
1.66
[root@localhost practice]# echo "scale=5;5/3"|bc #使用scale=5保留5位小数
1.66666
重:多种运算法拓展实践,通过一条命令输出1+2+3+...+10的表达式,并计算出结果。
打印表达式的命令如下:
[root@localhost practice]# seq -s "+" 10
1+2+3+4+5+6+7+8+9+10
[root@localhost practice]# echo {1..10}|tr " " "+"
1+2+3+4+5+6+7+8+9+10
实现本题的多种方法:
[root@localhost practice]# echo `seq -s "+" 10`=`seq -s "+" 10|bc` #使用bc计算,bc命令独有特点事除了支持证书运算之外,还支持小数运算
1+2+3+4+5+6+7+8+9+10=55
[root@localhost practice]# echo "`seq -s '+' 10`="$((`seq -s "+" 10`)) #使用"(( ))"计算
1+2+3+4+5+6+7+8+9+10=55
[root@localhost practice]# echo `seq -s '+' 10`=`seq -s " + " 10|xargs expr` #使用expr计算,注意用于计算的数字左右都至少有一个空格,否则会报错
1+2+3+4+5+6+7+8+9+10=55
[root@localhost practice]# echo `seq -s '+' 10`=$(echo $[`seq -s "+" 10`]) #使用$[ ]计算.
1+2+3+4+5+6+7+8+9+10=55
六:awk实现计算示例
awk进行运算效果也很好,适合小数和整数,特别是命令行计算,尤其是小数,运算很精确,并且方便。
[root@localhost practice]# echo "6.6 3.3"|awk '{print ($1-$2)}'
3.3
[root@localhost practice]# echo "6.6 3.3"|awk '{print ($1-2)/$2}'
1.39394
[root@localhost practice]# echo "6.6 3.3"|awk '{print ($1+2)*$2}'
28.38
七:$[ ]符号的运算示例
[root@localhost practice]# i=5
[root@localhost practice]# i=$[i+3]
[root@localhost practice]# echo $i
8
[root@localhost practice]# i=$[i-2]
[root@localhost practice]# echo $i
6
[root@localhost practice]# echo $[2*3]
6
[root@localhost practice]# echo $[2**3]
8
[root@localhost practice]# echo $[2/3]
0
[root@localhost practice]# echo $[2%3]
2
下面是解决问题的实例:打印杨辉三角
[root@localhost practice]# 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=$[i-1] #f=i-1 这是另一种计算写法。
g=$[j-1] #g=j-1 这是另一种计算写法。
if [ $j -eq $i ] || [ $j -eq 1 ] ; then
declare SUM_${i}_$j=1 #声明变量 头尾都是1
else
declare A=$[SUM_${f}_$j] #取上一行的j列变量
declare B=$[SUM_${f}_$g] #取上一行的j-1列变量
declare SUM_${i}_$j=`expr $A + $B` #声明并计算当前变量的值
fi
echo -en $[SUM_${i}_$j]" " #输出当前变量
let j++
done
echo #换行
let i++
done
八:基于Shell变量输入read命令的运算实践
1)read命令
语法格式:read 【参数】【变量名】
常用参数: -p(prompt) :设置提示信息 -t(timeout):设置输入等待的时间,单位默认为秒
read基本的读入功能示例:
[root@localhost practice]# read -t 5 -p "please input one num:" num #-t设置等待时间,时间超过就退出了,一般不设置这个值
please input one num:1
[root@localhost practice]# echo $num
1
[root@localhost practice]# read -p "please input two number:" a b #read的读入功能就相当于交互式接受用户输入,然后给变量赋值,体现了变量赋值灵活
please input two number:2 3
[root@localhost practice]# echo $a
2
[root@localhost practice]# echo $b
3
等价于echo -n "please input two number:" ;read a b
2)read运用于脚本变量读取赋值示例:
脚本1:
[root@localhost practice]# cat 3.sh
#!/bin/bash
echo -n "Enter your name:" #参数-n的作用是不换行,echo默认是换行
read name #从键盘输入
echo "hello $name,welcome to my program" #显示信息
exit 0 #退出shell程序。
[root@localhost practice]# sh 3.sh
Enter your name:ywxi
hello ywxi,welcome to my program
脚本2:
#该例子使用了-n选项,后接数值1个,指示read命令只要接受到一个字符就退出。只要按下一个字符进行回答,read命令立即接受输入并将其传给变量。无需按回车键。
[root@localhost practice]# cat 4.sh
#!/bin/bash
read -n1 -p "Do you want to continue [Y/N]: " answer
case $answer in
Y | y)
echo -e "\nfine ,continue";;
N | n)
echo "ok,good bye";;
*)
echo "error choice";;
esac
exit 0
[root@localhost practice]# sh 4.sh
Do you want to continue [Y/N]: Y
fine ,continue
[root@localhost practice]# sh 4.sh
Do you want to continue [Y/N]: y
fine ,continue
脚本3:
#最后,还可以使用read命令读取Linux系统上的文件。每次调用read命令都会读取文件中的"一行"文本。当文件没有可读的行时,read命令将以非零状态退出。
#读取文件的关键是如何将文本中的数据传送给read命令。
#最常用的方法是对文件使用cat命令并通过管道将结果直接传送给包含read命令的while命令。
[root@localhost practice]# 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
[root@localhost practice]# cat test
read
test
ywxi
[root@localhost practice]# sh 5.sh
Line 1:read
Line 2:test
Line 3:ywxi
finish