1. 程式人生 > 實用技巧 >五、Shell的變數之五變數的算數運算

五、Shell的變數之五變數的算數運算

一、算數運算子

+、-
加法(或正號)、減法(或符號)

*、/、%
乘法、除法、取餘(取模)

**
冪運算

++、——
增加及減少,可前置也可放在變數結尾

!、&&、||
邏輯非(取反)、邏輯與(and)、邏輯或(or)

<、<=、>、>=
比較符號(小於、小於等於、大於、大於等於)

==、!=、=
比較符號(相等、不等於,對於字串"=="表示相當於)

<<、>>
向左移位、向有移位

~、|、&、^
按位取反、按位異或、按位與、按位或

=、+=、-=、*=、/=、%=
賦值運算子,如a+=1相當於a=a+1
,a-=1相當於a=a-1

二、運算操作符與運算命令

(())
用於整數運算的常用運算子,效率很高

let
用於整數運算,類似於"(())"

expr
可用於整數運算,但也有很多其他的額外功能

bc
Linux下的一個計算器程式(適合整數和小數運算)

$[]
用於整數運算

awk
即可以用於整數計算,也可以用於小數計算

declare
定義變數值和屬性,-i引數可以用於定義整形變數,做運算

三、實驗案例

1、雙小括號"(())"

"(())"的運算

((i=i+1))
運算後賦值法,即將i+1的值賦值給i,不能用"echo ((i=i+1))"的形式輸出表達式的值,但可以用"
echo $((i=i+1))"輸出其值。 [root@node1 ~]# echo ((i=7+6)) -bash: syntax error near unexpected token `(' #上面為錯誤的輸出 [root@node1 ~]# echo $((i=7+6)) 13 [root@node1 ~]# ((a=1+2**3-4%3)) [root@node1 ~]# echo $a 8 等價於 [root@node1 ~]# echo $((1+2**3-4%3)) 8 [root@node1 ~]# a=10 [root@node1 ~]# echo $((a**2))
100

特殊運算子號

[root@node1 ~]# echo $a
8
[root@node1 ~]# echo $((1+2**3-4%3))
8
[root@node1 ~]# a=8
[root@node1 ~]# echo $((a=a+1))
9
[root@node1 ~]# echo $((a+=1)) #====echo $((a=a+1))
10

"(())"的比較及判斷

"(())"的比較,真值為1,假值為0
[root@node1 ~]# echo $((3<8))
1
[root@node1 ~]# echo $((3>8))
0
[root@node1 ~]# echo $((3==3))
1

判斷
[root@node1 ~]# if((8>7&&5==5))
> then
> echo yes
> fi
yes
#如果8>7且5==5,則列印yes

++的特殊運算表示式

[root@node1 ~]# a=10
[root@node1 ~]# echo $((a++))
10
[root@node1 ~]# echo $a
11
#執行完表示式後,a會自增1,再把值賦值給a
[root@node1 ~]# a=10
[root@node1 ~]# echo $((a--))
10
[root@node1 ~]# echo $a
9
#執行完表示式後,a會自減1,再把值賦值給a

[root@node1 ~]# a=10
[root@node1 ~]# echo $((++a))
11
[root@node1 ~]# echo $a
11
#先給a增加1,再執行表示式
[root@node1 ~]# a=10
[root@node1 ~]# echo $((--a))
9
[root@node1 ~]# echo $a
9
#先給a減少1,再執行表示式
++、——運算的記憶方法:
變數a在運算子之前,輸出表達式的值為a,然後a自增或自減;變數a在運算子之後,輸出表達式會先自增或自減,表示式的值就是自增或自減後a的值。

運算後賦值給變數

[root@node1 ~]# a=10
[root@node1 ~]# a=$((a+1))
[root@node1 ~]# echo $a
11
1) "(())"表示式在命令列執行時不需要加$符號,直接使用((62))形式即可,但是如果需要輸出,就要加$符,例如:echo $((62))。
2) "(())"裡的所有字元之間沒有空格、有一個或多個空格都不會影響結果。

各種"(())"運算的shell指令碼案例

#!/bin/bash
a=6                    #<==在指令碼中定義a和b兩個變數並分別賦值。
b=2
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))"

結果
a-b=4
a+b=8
a*b=12
a/b=3
a**b=36
a%b=0

2、let運算命令的用法

let運算命令的語法格式為:let賦值表示式

let賦值表示式的功能等同於“((賦值表示式))”

[root@node1 ~]# a=10
[root@node1 ~]# let a=a+2
[root@node1 ~]# echo $a
12
相當於
[root@node1 ~]# a=10
[root@node1 ~]# a=$((a+2))
[root@node1 ~]# echo $a
12

3、expr命令的用法

expr用於計算

[root@node1 ~]# expr 2 + 2
4
[root@node1 ~]# expr 2 * 2
expr: syntax error
[root@node1 ~]# expr 2 \* 2
4
[root@node1 ~]# expr 2 / 2
1
[root@node1 ~]# expr 2 % 2
0

要注意,在使用expr時:
·運算子及用於計算的數字左右都至少有一個空格,否則會報錯。
·使用乘號時,必須用反斜線遮蔽其特定含義,因為Shell可能會誤解星號的含義。

expr配合變數計算

expr在Shell中可配合變數進行計算,但需要用反引號將計算表示式括起來

[root@node1 ~]# a=10
[root@node1 ~]# b=`expr $a + 6`
[root@node1 ~]# echo $b
16

判斷一個變數值或字串是否為整數

實現原理是,利用以expr做計算時變數或字串必須是整數的規則,把一個變數或字串和一個已知的整數(非0)相加,看命令返回的值是否為0。如果為0,就認為做加法的變數或字串為整數,否則就不是整數。

[root@node1 ~]# i=5
[root@node1 ~]# expr $i + 6 &>/dev/null
[root@node1 ~]# echo $?
0

[root@node1 ~]# i=kaka
[root@node1 ~]# expr $i + 6 &>/dev/null
[root@node1 ~]# echo $?
2
#利用expr做計算,將一個未知的變數和一個已知的整數相加,看返回值是否為0,如果為0就認為做加法的變數為整數,否則就不是整數。

通過傳參判斷輸出內容是否為整數

[root@node1 tmp]# cat expr.sh
#!/bin/sh
expr $1 + 1 >/dev/null 2>&1
[ $? -eq 0 ] &&echo int||echo chars  #<==這是一個條件表示式語法,返回值為0,則輸出int,否則輸出chars。
[root@node1 tmp]# sh /tmp/expr.sh 5
int
[root@node1 tmp]# sh /tmp/expr.sh kaka
chars

expr的特殊用法:判斷檔案擴充套件命名是否符合要求

[root@node1 tmp]# cat expr1.sh
#!/bin/sh
if expr "$1" : ".*\.pub" &>/dev/null
  then
    echo "you are using $1"
else
    echo "pls use *.pub file"
fi
[root@node1 tmp]# sh expr1.sh kaka
pls use *.pub file
[root@node1 tmp]# sh expr1.sh king.pub
you are using king.pub

通過expr計算字串的長度

[root@node1 tmp]# a="ni hao da hai"
[root@node1 tmp]# expr length "$a"
13
#包含空格

4、bc命令的用法

將bc作為計算器來應用

[root@node1 tmp]# 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
[root@node1 tmp]# echo 3+4|bc
7
[root@node1 tmp]# echo 3.3+4|bc
7.3
[root@node1 tmp]# echo 8.3+4.7|bc
13.0
[root@node1 tmp]# echo 8.3-4.7|bc
3.6
[root@node1 tmp]# echo "scale=2;8.3-4.7"|bc
3.6
[root@node1 tmp]# echo "scale=2;8.3/4.7"|bc
1.76
[root@node1 tmp]# echo "scale=6;355/113"|bc   #scale保留小數點後幾位
3.141592

利用bc配合變數運算

[root@node1 tmp]# i=5
[root@node1 tmp]# i=`echo $i+6|bc`
[root@node1 tmp]# echo $i
11

5、awk實現計算

利用awk進行運算的效果也很好,適合小數和整數,特別是命令列計算,尤其是小數,運算很精確
[root@node1 tmp]# echo "7.8 4.5"|awk '{print ($1-$2)}'
3.3
[root@node1 tmp]# echo "358 113" |awk '{print ($1-3)/$2}'
3.14159
[root@node1 tmp]# echo "3 9" |awk '{print ($1+3)*$2}'
54

6、declare(同typeset)命令的用法

[root@node1 tmp]# declare -i A=30 B=7 #<==declare -i引數可以將變數定義為整形。
[root@node1 tmp]# A=A+B  #<==因為已宣告是整型,因此可以直接進行運算了。
[root@node1 tmp]# echo $A
37  #<==結果為37

7、$[]符號的運算示例

[root@node1 tmp]# i=5
[root@node1 tmp]# i=$[i+6]
[root@node1 tmp]# echo $i
11
[root@node1 tmp]# echo $[2*3]
6
[root@node1 tmp]# echo $[2**3]
8
[root@node1 tmp]# echo $[3/5]
0
[root@node1 tmp]# echo $[3/2]
1
[root@node1 tmp]# echo $[35]
3
[root@node1 tmp]# echo $[ 35 ]
3

四、基於Shell變數輸入read命令的運算實踐

Shell變數除了可以直接賦值或指令碼傳參外,還可以使用read命令從標準輸入中獲得,read為bash內建命令,可通過help read檢視幫助。
語法格式:read[引數][變數名]

常用引數如下。
·-p prompt:設定提示資訊。
·-t timeout:設定輸入等待的時間,單位預設為秒。

實現read的基本讀入功能。

[root@node1 tmp]# read -t 10 -p "Pls input one num:" num
#<==讀入一個輸入,賦值給num變數,注意,num變數前需要有空格。
Pls input one num:18             #<==輸出數字18,相當於把18賦值給num變數。
[root@node1 tmp]# echo $num #<==輸出變數值。
[root@node1 tmp]# read -p "please input two number:" a1 a2
#<==讀入兩個輸入,注意要以空格隔開,分別賦值給a1和a2變數,a1變數前後都需要有空格。
please input two number:1 2
[root@node1 tmp]# echo $a1
1
[root@node1 tmp]# echo $a2
2

把前面加減乘除計算傳參的指令碼改成通過read方式讀入整數變數

#!/bin/bash
read -t 15 -p "please input two number:" a b  #<==去掉原指令碼中a和b的定義,通
                                                 過read讀入即可。
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))"