bash 不支持浮點運算,如果需要進(jìn)行浮點運算,需要借助bc,awk 處理
expr命令
=======
最開始,Bourne shell提供了一個特別的命令用來處理數(shù)學(xué)表達(dá)式。expr命令允許在命令行上處理數(shù)學(xué)表達(dá)式,但是特別笨拙:
$ expr 1 + 5
6
expr命令能識別一些不同的數(shù)字和字符串操作符,如下表:
=======================================================================
操作符 描 述
-----------------------------------------------------------------------
ARG1 | ARG2 如果沒有參數(shù)是null或0,返回ARG1;否則返回ARG2
ARG1 & ARG2 如果沒有參數(shù)是null或0,返回ARG1;否則返回0
ARG1 < ARG2 如果ARG1小于ARG2,返回1;否則返回0
ARG1 <= ARG2 如果ARG1小于或等于ARG2,返回1;否則返回0
ARG1 = ARG2 如果ARG1等于ARG2,返回1;否則返回0
ARG1 != ARG2 如果ARG1不等于ARG2,返回1;否則返回0
ARG1 >= ARG2 如果ARG1大于或等于ARG2,返回1;否則返回0
ARG1 > ARG2 如果ARG1大于ARG2,返回1;否則返回0
ARG1 + ARG2 返回ARG1和ARG2的算術(shù)運算和
ARG1 - ARG2 返回ARG1和ARG2的算術(shù)運算差
ARG1 * ARG2 返回ARG1和ARG2的算術(shù)乘積
ARG1 / ARG2 返回ARG1和ARG2的算術(shù)商
ARG1 % ARG2 返回ARG1和ARG2的算術(shù)余數(shù)
STR : EXP 如果EXP匹配到STR的某個模式,返回該模式匹配
match STR EXP 如果EXP匹配到STR的某個模式,返回該模式匹配
substr STR POS LEN 返回起始位置為POS(從1開始計數(shù))、長度為LEN個字符的字符串
index STR CHARS 返回在STR中找到CHARS字符串的位置;否則,返回0
length STR 返回字符串STR的數(shù)值長度
+ TOKEN 將TOKEN解釋成字符串,即使是個關(guān)鍵字
(EXPRESSION) 返回EXPRESSION的值
=======================================================================
盡管標(biāo)準(zhǔn)操作符在expr命令中工作得很好,但在腳本或命令行上使用它們時仍有問題出現(xiàn)。許多expr命令操作符在shell中有其他意思(比如星號)。在expr命令中使用它們會得到一些詭異的結(jié)果:
$ expr 5 * 2
expr: syntax error
$
要解決這個問題,在傳給expr命令前,你需要使用shell的轉(zhuǎn)義字符(反斜線)來識別容易被shell錯誤解釋的任意字符:
$ expr 5 \* 2
10
$
不過,bash shell有一個針對處理數(shù)學(xué)運算符的改進(jìn),請看下面。
使用方括號
========
bash shell為了保持跟Bourne shell兼容而包含了expr命令,但它同樣也提供了一個執(zhí)行數(shù)學(xué)表達(dá)式更簡單的方法。在bash shell中,在將一個數(shù)學(xué)運算結(jié)果賦給某個變量時,你可以用美元符和方括號($[ operation ])將數(shù)學(xué)表達(dá)式圈起來:
$ var1=$[1 + 5]
$ echo $var1
6
$ var2=$[$var1 * 2]
$ echo $var2
12
$
用方括號來執(zhí)行shell數(shù)學(xué)運算比用expr命令方便很多,這種技術(shù)在shell腳本中也能工作。同樣,在使用方括號來計算公式時,不用擔(dān)心shell會誤解乘號或其他符號。shell知道它不是通配符,因為它在方括號內(nèi)。
但是,bash shell數(shù)學(xué)運算只支持整數(shù)運算。如果要計算浮點,請往下看。
浮點解決方案
==========
有幾種解決方案能夠解決bash中數(shù)學(xué)運算的整數(shù)限制。最常見的解決方法是有內(nèi)建的bash計算器,稱作bc。
###bc的基本用法
bash計算器其實是允許你在命令行輸入浮點表達(dá)式、解釋表達(dá)式、計算并返回結(jié)果的一種編程語言。bash計算器能夠識別:
- 數(shù)字(整數(shù)和浮點數(shù))
- 變量(簡單變量和數(shù)組)
- 注釋(以#開始的行或者C語言中的/* */對)
- 表達(dá)式
- 編程語句(例如if-then)
- 函數(shù)
你可以在shell提示符下通過bc命令訪問bash計算器:
$ 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'.
12*5.4
64.8
quit
輸入計算公式,bc會自動返回答案,退出輸入quit。
浮點運算是由一個內(nèi)建的稱為scale的變量控制的。你必須將這個值設(shè)置為結(jié)果是你想要的小數(shù)后的位數(shù)。
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'.
3.44 /5
0
scale=4
3.44 /5
.6880
quit
###在腳本中使用bc
你可以使用反引號或者$()來運行bc命令并將輸出賦給一個變量?;靖袷绞沁@樣的:
variable = `echo "options; expression" | bc`
第一部分options允許你來設(shè)置變量。如果你需要設(shè)置不止一個變量,可以用分號來分開它們。expression變量定義了通過bc執(zhí)行的數(shù)學(xué)表達(dá)式。例子:
#!/bin/bash
var1=`echo "scale=4; 3.44 / 5" | bc`
echo The answer is $var1
結(jié)果是: The answer is .6880
這種方法適用于較短的運算,但有時你會更多地和你自己的數(shù)字打交道。如果你有很多運算,在同一個命令行中列出多個表達(dá)式就會有點麻煩。
針對這個問題有個解決辦法。bc命令能識別輸入重定向,允許你將一個文件重定向到bc命令來處理。然后,這同樣會叫要困惑,因為你必須將表達(dá)式存儲到文件中。
最好的辦法是使用內(nèi)聯(lián)輸入重定向,允許你直接在控制臺重定向數(shù)據(jù)。在shell腳本中,你可以將輸出賦給一個變量:
variable=`bc << EOF
options
statements
expressions
EOF
`
EOF文件字符串標(biāo)識了內(nèi)聯(lián)重定向數(shù)據(jù)的開始和結(jié)尾。記住仍然需要反引號來將bc命令的輸出賦給變量。例如:
#!/bin/bash
var1=10.46
var2=43.67
var3=33.2
var4=71
var5=`bc << EOF
scale = 4
a1 = ($var1 * $var2)
b1 = ($var3 * $var4)
a1 + b1
EOF
`
echo The final answer for this mass is $var5