bash&shell系列文章:http://www.cnblogs.com/f-ck-need-u/p/7048359.html
使用let、(())、$(())或$[]進行基本的整數運算,使用bc進行高級的運算,包括小數運算。其中expr命令也能進行整數運算,還能判斷參數是否為整數,具體用法見expr命令全解。
其中let和(())幾乎完全等價,除了做數學運算,還支持數學表達式判斷,例如數值變量a是否等於3:let a==3或((a==3)),但一般不會使用它們來判斷,而是使用test命令結合條件表達式:test "$a" -eq 3。因此,本文只介紹let的賦值運算功能。
1.6.1 基本整數運算
[root@xuexi tmp]# str=10 [root@xuexi tmp]# let str=str+6 # 等價於let str+=6 [root@xuexi tmp]# let str-=5 # 等價於let str=str-5 [root@xuexi tmp]# echo $str 11
let也可以使用(( ))進行替換,它們幾乎完全等價。且額外的功能是:如果最后一個算術表達式結果為0,則返回狀態碼1,其余時候返回狀態碼0。
如果想在命令行中做計算,則可以使用$(())或$[]。
[root@xuexi ~]# str=10 [root@xuexi ~]# echo $((str+=6)) 16 [root@xuexi ~]# echo $[str=str-6] 10
當然,在為變量賦算術值的時候也可以使用$(())和$[]。
[root@xuexi ~]# str=10 [root@xuexi ~]# str=$((str+=6));echo $str 16 [root@xuexi ~]# str=$[str-=6];echo $str 10
其實,在算數計算過程中,等號右邊的變量是可以帶上$符號的,但等號左邊的變量不允許帶上$符號,因為它是要操作的變量,不是引用變量。例如:
[root@xuexi ~]# let str=$str-1 # 等價於let str=str-1 [root@xuexi ~]# str=$(($str-1)) # 等價於str=$((str-1)) [root@xuexi ~]# srt=$[$str-1] # 等價於str=$[str-1] [root@xuexi ~]# echo $((str=$str-1)) # 等價於echo $((str=str-1)),但不能寫成echo $(($str=str-1)) [root@xuexi ~]# echo $[str=$str-1] # 等價於echo $[str=str-1],但不能寫成echo $[$str=str-1]
還可以自增、自減運算。"++"和"--"表示變量自動加1和減1。但是位置不同,返回的結果是不同的。
x++:先返回結果,再加1
++x:先加1再返回結果
x--:先返回結果,再減1
--x:先減1再返回結果
假如x的初始值為10,則echo $[x++]將顯示10,但在顯示完后(即返回結果之后),x的值已經變成了11,再執行echo $x將返回11。
[root@xuexi ~]# x=10;echo $((x++));echo $x 10 11
如果此時再echo $[x++]仍將返回11,但此時x已經是12了。
[root@xuexi ~]# echo $((x++));echo $x 11 12
再將x變量的初始值初始化為10,則echo $[++x]將顯示11,因為先加1后再賦值給x,echo再顯示x的值。++x完全等價於x=x+1,它們都是先加1后賦值。
[root@xuexi ~]# x=10;echo $((++x));echo $x 11 11
同理自減也是一樣的。
因此,在使用自增或自減進行變量賦值時,需要注意所賦的值是否加減立即生效的。例如:
[root@xuexi ~]# x=10;y=$((x++));echo $y;echo $y 10 10
因為y=$((x++))賦給y的值是加1前的值,雖然賦值結束后,$((x++))已經變成11,但這和y無關。
所以,對於自增自減類的變量賦值應該使用先計算再顯示的"++x"或"--x"的方式。
[root@xuexi ~]# x=10;y=$((++x));echo $y;echo $y 11 11
總結下數值變量的賦值運算的方法:
let i=i-1
let i=$i-1
let i-=1
i=$((i-1))
i=$(($i-1))
i=$[ i - 1 ]
i=$[ $i - 1 ]
echo $((i=i-1))
echo $((i=$i-1))
除了變量可以數學運算,數組也一樣支持數學運算,且和變量一樣,都能支持自增和自減等操作。其實數組其實質就是變量,只不過變量在內存中是離散的空間,而數組在內存中是順序的空間。
例如,數組arr_test[a]=10,則:
let arr_test[a]=${arr_test[0]} - 1
let arr_test[a]-=1
echo $((arr_test[a]++))
echo $[ arr_test[a]++ ]
其它運算方法都類似,就不贅述了。其實和變量相比,只不過變量名改成arr_test[a],引用數組變量時改為${arr_test[a]}。
1.6.2 bc命令高級算術運算
bc可用於浮點數的計算,是linux中的計算器。該命令功能豐富、強大的讓人吐血,支持自定義變量、自定義函數表達式邏輯、支持科學計算等等。雖然功能豐富,但多數時候僅用它的基本計算功能。
以下是一個基本的功能示例:
[root@node1 ~]# bc b 1.06.95 # 首先輸出bc的版本信息,可以使用-q選項不輸出頭部信息 Copyright 1991-1994, 197, 1998, 2000, 2004, 2006 Free Software Foundation, Inc. This is free software with ABSOLUTELY NO WARRANTY. For details type `warranty'. pie=3.1415 # 可以變量賦值 pie*3*3 # 運算時不需要空格 28.2735 r=3 pie*r*r 28.2735 pie*r^2 # 可以使用冪次方 28.2735 r=3 /* 將半徑設置為3 */ # 還可以使用C語言風格的注釋
輸入quit命令可以退出bc計算器。
還支持自增和自減的功能。
[root@node1 ~]# bc -q r=3 r++ 3 r++ 4 ++r 6 ++r 7 --r 6
bc運算器有一個內建的變量scale,用於表示計算的精度(其實是刻度),即小數位保留幾位。默認刻度為0,所以除法運算的默認結果是整數。
13/(1+3) 3 scale=3 13/(1+3) 3.250
更人性化的功能是可以通過命令替換來實現批處理模式的計算。
它的一般格式參考如下:
var=`echo "option1;option2;...;expression"|bc`
其中options部分一般設置精度scale,和變量賦值,expression部分是計算表達式,最后將它們放在反引號中賦值給變量。如:
[root@node1 ~]# area=`echo "scale=2;r=3;3.1415*r*r"|bc` [root@xuexi ~]# echo $area 28.2735
由於是在命令行中指定,所以這樣的使用方式限制較多。bc接受使用here string和here document的方式接收參數。最常做法是將它們放置於腳本中。
#!/bin/bash # script for calculate something var1=haha var2=hehe value=`bc<<EOF # 在反引號中使用here string的方式 scale=3 r=3 3.1415*r*r EOF` echo $value
當bc計算的結果小於1的時候,例如"0.1+0.1=0.2",它會顯示".2"而不是顯示"0.2",要想顯示出前面的0,bc自身似乎沒有做出相關選項。不過可以通過外部程序,如printf將其顯示出來。也可以結合echo命令顯示。
printf "%.2f\n" `echo "0.1 + 0.1" | bc` 0.30 echo 0`echo "0.1 + 0.1" | bc` 0.3
以下是計算1+2+...+10的幾種不同方式,要求輸出在屏幕上的結果為"1+2+3+4+5+6+7+8+9+10=計算結果",這是非常不錯的例子。
[root@node1 tmp]# echo $(seq -s "+" 10)=`seq -s "+" 10|bc` 1+2+3+4+5+6+7+8+9+10=55
[root@node1 tmp]# echo $(seq -s "+" 10)=$((`seq -s "+" 10`)) 1+2+3+4+5+6+7+8+9+10=55
[root@node1 tmp]# echo $(seq -s "+" 10)=$(seq -s " + " 10|xargs expr) # 注意"+"和" + " 1+2+3+4+5+6+7+8+9+10=55