在Linux下作算術運算時你是如何進行的呢?是否是還在用expr呢?你會說我還會bc還有其它的呢!正則表達式
閒話很少扯,幹正事!shell
expr在使用中要注意一些書寫,如表達式中量和運算符號之間的空格及一些運算符號須要轉義,還有一點須要記住,expr只適用於整數之間的運算!函數
expr的help文檔中關於表達式部分以下:ui
ARG1 | ARG2 若ARG1 的值不爲0 或者爲空,則返回ARG1,不然返回ARG2 ARG1 & ARG2 若兩邊的值都不爲0 或爲空,則返回ARG1,不然返回 0 ARG1 < ARG2 ARG1 小於ARG2 ARG1 <= ARG2 ARG1 小於或等於ARG2 ARG1 = ARG2 ARG1 等於ARG2 ARG1 != ARG2 ARG1 不等於ARG2 ARG1 >= ARG2 ARG1 大於或等於ARG2 ARG1 > ARG2 ARG1 大於ARG2 ARG1 + ARG2 計算 ARG1 與ARG2 相加之和 ARG1 - ARG2 計算 ARG1 與ARG2 相減之差 ARG1 * ARG2 計算 ARG1 與ARG2 相乘之積 ARG1 / ARG2 計算 ARG1 與ARG2 相除之商 ARG1 % ARG2 計算 ARG1 與ARG2 相除之餘數
這一部分相信你們用的最多,也對這些比較瞭解了,下面咱們用一個表達式來講明:spa
$expr 9 + 8 - 7 \* 6 / 5 + \( 4 - 3 \) \* 2 11
經過結果相信你已知道expr的計算規律,它與咱們平常所理解的數學表達式同樣,括號的優先級最高,而後是「*」、「/」,並且每一個數或符號都須要用空格分隔,結果也是整數。命令行
expr還能夠對字符串進行操做:code
match 字符串 表達式等於"字符串 :表達式" substr 字符串 偏移量 長度替換字符串的子串,偏移的數值從 1 起計 index 字符串 字符在字符串中發現字符的地方創建下標,或者標0 length 字符串字符串的長度
1)matchblog
expr中的expr match $string substring命令在string字符串中匹配substring字符串(substring字符串能夠是正則表達式),而後返回匹配到的substring字符串的長度,若找不到則返回0。索引
下面咱們來個實例:文檔
┌[2013-08-24/7.18 15:00:01] ├[14+1][~] └[snowsolf@Ubuntu-LTS-1 ╰_╯]$str="123 456 789" ┌[2013-08-24/7.18 15:00:30] ├[14+1][~] └[snowsolf@Ubuntu-LTS-1 ╰_╯]$expr match "$str" .*5 6
.*5匹配了6個字符。
2)substr
在shell中能夠用{string:position}和{string:position:length}進行對string字符串中字符的抽取。第一種是從position位置開始抽取直到字符串結束,第二種是從position位置開始抽取長度爲length的子串。而用expr中的expr substr $string $position $length一樣能實現上述功能。
實例:
┌[2013-08-24/7.18 15:19:17] ├[14+1][~] └[snowsolf@Ubuntu-LTS-1 ╰_╯]$str="123 456 789" ┌[2013-08-24/7.18 15:19:31] ├[14+1][~] └[snowsolf@Ubuntu-LTS-1 ╰_╯]$echo ${str:5} 56 789 ┌[2013-08-24/7.18 15:19:59] ├[14+1][~] └[snowsolf@Ubuntu-LTS-1 ╰_╯]$echo ${str:5:3} 56 ┌[2013-08-24/7.18 15:20:07] ├[14+1][~] └[snowsolf@Ubuntu-LTS-1 ╰_╯]$expr substr "$str" 5 3 456
從中能夠看出{string:position}和{string:position:length}從0開始計數,而expr substr $string $position $length從1開始。
3)index
expr中的expr index $string substring索引命令功能在字符串$string上找出substring中字符第一次出現的位置,若找不到則expr index返回0。注意它匹配的是字符而非字符串。
實例:
┌[2013-08-24/7.18 15:35:19] ├[14+1][~] └[snowsolf@Ubuntu-LTS-1 ╰_╯]$str="123 456 789" ┌[2013-08-24/7.18 15:37:02] ├[14+1][~] └[snowsolf@Ubuntu-LTS-1 ╰_╯]$expr index "$str" b 0 ┌[2013-08-24/7.18 15:37:08] ├[14+1][~] └[snowsolf@Ubuntu-LTS-1 ╰_╯]$expr index "$str" 9 11
4)length
計算字符串的長度。咱們能夠用awk中的length(s)進行計算。咱們也能夠用echo中的echo ${#string}進行計算,固然也能夠expr中的expr length $string 求出字符串的長度。
┌[2013-08-24/7.18 15:39:39] ├[14+1][~] └[snowsolf@Ubuntu-LTS-1 ╰_╯]$str="123 456 789" ┌[2013-08-24/7.18 15:39:52] ├[14+1][~] └[snowsolf@Ubuntu-LTS-1 ╰_╯]$echo ${#str} 11 ┌[2013-08-24/7.18 15:39:57] ├[14+1][~] └[snowsolf@Ubuntu-LTS-1 ╰_╯]$expr length "$str" 11
重點來了!
bc是一種任意精度的計算語言,注意是一種語言,它提供了一些語法結構,好比條件判斷、循環等,能夠說是很強大的,可是我在實際中尚未找到須要這個用途的場合 。另一個用途就是用來進行進制轉換。
上面咱們介紹的expr之支持整數運算,但對於浮點運算就無能爲力了,並且expr不能進行指數運算,而都有bc這些都再也不話下。
咱們先來了解幾個有用的參數:
-i 強制交互模式; -l 使用bc的內置庫,bc裏有一些數學庫,對三角計算等很是實用; -q 進入bc交互模式時再也不輸出版本等多餘的信息。
ibase,obase 用於進制轉換,ibase是輸入的進制,obase是輸出的進制,默認是十進制;
scale 小數保留位數,默認保留0位。
在shell命令行直接輸入bc及能進入bc語言的交互模式。
$bc -l -q 4/3 /*未指定精度默認保留整數*/ 1 scale=5 /*指定精度爲5*/ 4/3 1.33333 ibase=2 /*指定進制轉換的輸入機制爲二進制,輸出默認爲是十進制*/ 1010 10 4^2 /*指數運算,注:指數不能爲浮點數*/ 16 4*a(1) /*計算π值,a()是個函數:arctan(),好吧,老師教的都被狗吃了,π值是等於四倍的arctan(1)麼?*/ 3.14159265358979323844 quit /*退出*/
bc也能夠進行非交互式的運算,方法是與echo一塊兒使用。
┌[2013-08-24/7.18 18:42:27] ├[14+1][~] └[snowsolf@Ubuntu-LTS-1 ╰_╯]$echo "scale=5;9+8-7*6/5^2"|bc /*優先級^ > *、/ > +、- */ 15.32000 ┌[2013-08-24/7.18 18:45:35] ├[14+1][~] └[snowsolf@Ubuntu-LTS-1 ╰_╯]$echo "s(2/3*a(1))"|bc -l /*還記得sina(30°)等於0.5麼?皇上! ^_^*/ .49999999999999999998 ┌[2013-08-24/7.18 18:49:13] ├[14+1][~] └[snowsolf@Ubuntu-LTS-1 ╰_╯]$echo "scale=5;sqrt(15)"|bc /*開方*/ 3.87298 ┌[2013-08-24/7.18 18:49:18] ├[14+1][~] └[snowsolf@Ubuntu-LTS-1 ╰_╯]$echo "ibase=16;obase=2;ABC"|bc 101010111100
更多參考man文檔!
可能你曾經知道有此命令,也可能你還不知道。dc相比與bc要複雜,可是簡單操做仍是比較簡單。簡單的說dc是一直壓棧操做,和bc同樣,它也能夠交互使用,或者與echo一塊兒配合使用。
它也支持浮點運算。
可是如今我尚未想到這種壓棧式算術運算有什麼有點。
┌[2013-09-16/8.12 20:33:53] ├[7+10][~/shell] └[snowsolf@Ubuntu-LTS-1 ╰_╯]$dc 2 3- p /*輸出(3 - 2)*/ -1 4 * p /*輸出(-1 * 4)*/ -4 2 / p /*輸出(-4 / 2)*/ -2 3.4 + p /*輸出(-2 + 3.4)*/ 1.4 4 d /*複製棧頂值*/ * p /*輸出(4 * 4)*/ 16 q /*退出*/
還有其餘命令如:
c 清除壓棧
d 複製棧頂的值
p 輸出棧頂值
q 退出交互模式
還有其它能夠參考對應man文檔。
一個算式讓你就看的差很少了。
┌[2013-09-16/8.12 20:47:43] ├[7+10][~/shell] └[snowsolf@Ubuntu-LTS-1 ╰_╯]$echo "4 3 * 2 + 1 -p"|dc 13
算式是:(4 * 3 + 2 - 1)。
是否是很簡單!
這兩個在shell中比較常見,這兩個和expr命令有些相似,也是用於整數計算。
他們支持的運算符號有以下:
| 位或 + || 若先後二者都不爲0,則返回1,不然返回0 & 位與 + && 若前者爲0,再也不對後者進行處理,不然對後者處理,後者不爲0時返回1 < <= == != >= > + - * / %
帶+號的兩個運算符實際上是shell支持的運算符。
這兩個對與expr的優勢是:運算符號所有不須要轉義。
咱們一味的在shell中用那些別人沒用過的命令來作同一件事,但不要忘了(( ))和[ ]是shell中常見的,並且很是實用,但並不是是你經常使用的!
實例:
┌[2013-09-16/8.12 20:47:51] ├[7+10][~/shell] └[snowsolf@Ubuntu-LTS-1 ╰_╯]$echo $(( 2 + 5 )) 7 ┌[2013-09-16/8.12 21:11:14] ├[7+10][~/shell] └[snowsolf@Ubuntu-LTS-1 ╰_╯]$echo $(( 2 * 5 )) 10 ┌[2013-09-16/8.12 21:11:19] ├[7+10][~/shell] └[snowsolf@Ubuntu-LTS-1 ╰_╯]$echo $(( 2 - 5 )) -3 ┌[2013-09-16/8.12 21:11:23] ├[7+10][~/shell] └[snowsolf@Ubuntu-LTS-1 ╰_╯]$echo $(( 2 % 5 )) 2 ┌[2013-09-16/8.12 21:11:29] ├[7+10][~/shell] └[snowsolf@Ubuntu-LTS-1 ╰_╯]$echo $[ 2 % 5 ] 2 ┌[2013-09-16/8.12 21:11:45] ├[7+10][~/shell] └[snowsolf@Ubuntu-LTS-1 ╰_╯]$echo $[ 2 - 5 ] -3 ┌[2013-09-16/8.12 21:11:50] ├[7+10][~/shell] └[snowsolf@Ubuntu-LTS-1 ╰_╯]$echo $[ 2 * 5 ] 10 ┌[2013-09-16/8.12 21:11:55] ├[7+10][~/shell] └[snowsolf@Ubuntu-LTS-1 ╰_╯]$echo $[ 2 + 5 ] 7