SHELL腳本--數學運算和bc命令


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 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM