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