shell中變量的數值計算
1、變量字符串長度計算及耗時對比
1.1、計算變量字符串長度的不同方法
[root@localhost ~]# chars=`seq -s " " 100` #定義一個以空格爲分隔符1-100的變量
[root@localhost ~]# echo ${#chars} #使用系統內置的變量計算變量的長度
291
[root@localhost ~]# echo ${chars}|wc -m #使用wc命令計算變量的長度
292
[root@localhost ~]# echo $(expr length $chars) #因爲$chars變量沒有加引號導致錯誤
expr: 語法錯誤
[root@localhost ~]# echo $(expr length "$chars") #使用expr命令計算變量長度
291
1.2、不同計算方法的耗時對比
[root@localhost ~]# time for i in $(seq 10000);do count=${#chars};done
real 0m0.222s
user 0m0.216s
sys 0m0.006s
[root@localhost ~]# time for i in $(seq 10000);do count=`echo ${chars}|wc -m`;done
real 0m20.653s
user 0m5.381s
sys 0m15.174s
[root@localhost ~]# time for i in $(seq 10000);do count=`echo expr length "${chars}"`;done
real 0m4.701s
user 0m0.711s
sys 0m3.970s
從上面的實驗可以看出,調用外部的命令處理相比內置的功能操作性能相差較大。在shell編程中我們應該儘量使用系統內置的命令來進行處理。
2、變量的運算符及數值計算
變量的數值計算常見有以下幾個命令
(( ))、let、expr、bc、$[ ]
2.1、雙括號(( ))用法(此方法很常用)
執行簡單的整數運算,只需將特定的算術表達式用雙括號括起來即可
下表列出了常用的算術運算符,假定變量 a=10,變量 b=20
運算符 | 說明 | 舉例 |
+ | 加法 | $((a+b))結果爲 30 |
- | 減法 | $((a-b))結果爲 10 |
* | 乘法 | $((a*b))結果爲 200 |
/ | 除法 | $((a/b))結果爲 2 |
% | 取餘(取模) | $((a%b))結果爲 0 |
** | 冪運算 | $((a**2))結果爲100 |
= | 賦值 | a=$b把變量 b 的值賦給 a |
+= | 加等於 | $((a+=5))等於$((a=a+5)) |
-= | 減等於 | $((a-=5))等於$((a=a-5)) |
*= | 乘等於 | $((a*=5))等於$((a=a*5)) |
/= | 除等於 | $((a/=5))等於$((a=a/5)) |
%= | 取模賦值 | $((a%=5))等於$((a=a%5)) |
== | 相等。用於比較兩個數字 | [ 4==5 ] 返回0;0表示假,1表示真 |
!= | 不相等。用於比較兩個數字 | [ $a != $b ] 返回1;0表示假,1表示真 |
<,<= | 小於,小於等於,比較數值 | [ $a < $b ] 返回1;0表示假,1表示真 |
>,>= | 大於,大於等於,比較數值 | [ $a < $b ] 返回0;0表示假,1表示真 |
++,-- | 自加,自減 | $((a--))返回10;$((--a))返回9 |
注意:條件表達式要放在方括號之間,並且要有空格,例如: [$a==$b] 是錯誤的,必須寫成 [ $a == $b ]。
計算從1加到100的值
[root@localhost ~]# echo $((100*(100+1)/2))
5050
提示:
1、上面涉及到的參數變量必須爲整數(整型),不能是小數(浮點數)或者字符串,下面介紹的bc命令可以進行浮點數運算,但一般較少使用。
2、echo $((a++))和echo $((a--))表示先輸出a自身的值,然後再進行++ --的運算,echo $((++a))和echo $((--a))表示先進行++ --運算,再輸出a自身的值。
2.2、let命令用法
格式:let 賦值表達式
提示:let賦值表達式功能等同於((賦值表達式))
[root@localhost ~]# i=100
[root@localhost ~]# let i=i+6
[root@localhost ~]# echo $i
106
[root@localhost ~]# i=i+6 #去掉let定義
[root@localhost ~]# echo $i
i+6
提示:let i=i+6等同於((i=i+6)),但後者效率更高。
2.3、expr(evaluate expressions)命令用法
expr命令一般用於整數值計算,也可以用於字符串,用來求表達式變量的值。
[root@localhost ~]# expr 4 + 5
9
[root@localhost ~]# expr 4 * 5
expr: 語法錯誤
[root@localhost ~]# expr 4 \* 5 #這裏乘法需要轉義
20
[root@localhost ~]# expr 4+5
4+5
[root@localhost ~]# expr $[4+5]
9
注意:運算符兩邊必須有空格,不然會輸出字符串,也可以使用中括號的方式進行運算不需要空格。
2.4、expr特殊用法(判斷文件擴展名和變量是否爲整數)
2.4.1、判斷文件擴展名用法
判斷前面文件的擴展名和後面指定的擴展名是否相同,如果相同則輸出前面文件名稱字符串的個數,如果擴展名不相同則輸出0
[root@localhost ~]# expr "abc.txt" : ".*\.pub"
0
[root@localhost ~]# expr "abc.pub" : ".*\.pub"
7
2.4.2、通過expr判斷一個變量是否爲整數
[root@localhost ~]# vim 1.sh
#!/bin/bash
read -p "請輸入數字:" a
expr $[a+0] &>/dev/null
[ $? -eq 0 ] && echo "你輸入的是數字" || echo "你輸入的不是數字"
更多用法請使用man expr查看
2.5、bc命令的用法(支持小數運算及進制轉換)
直接在命令行輸入bc命令可進入計算模式,這時候可以輸入表達式計算,bc命令可以計算小數,也可以把表達式輸出到bc進行處理。對於除法,bc命令默認只能整除,需要保留小數需要加scale=數字,方式來說明保留幾位小數。
例1:從1加到100
[root@localhost ~]# seq -s "+" 100|bc
5050
例2:做小數運算
[root@localhost ~]# echo "5.35+6"|bc
11.35
[root@localhost ~]# echo "5.35*2.3"|bc
12.30
[root@localhost ~]# echo "5.35/2.3"|bc #默認整除不保留小數
2
[root@localhost ~]# echo "scale=3;5.35/2.3"|bc #保留3位小數
2.326
[root@localhost ~]# echo "obase=2;20"|bc #把20轉換成2進制
10100
[root@localhost ~]# echo "obase=8;20"|bc #把20轉換成8進制
24
[root@localhost ~]# echo "obase=16;20"|bc #把20轉換成16進制
14
2.6、$[ ]用法
[root@localhost ~]# echo $[2+3]
5
[root@localhost ~]# echo $[ 2.5+3 ]
-bash: 2.5+3 : 語法錯誤: 無效的算術運算符 (錯誤符號是 ".5+3 ")
[root@localhost ~]# echo $[ 5-3 ]
2
2.7、read使用方法
shell變量除了可以直接賦值或腳本傳參外,還可以使用read命令從標準輸入獲得。語法格式:read 參數 變量名
常用參數:-p prompt 設置提示信息
-t timeout 設置輸入等待的時間,單位默認爲秒
例:
[root@localhost ~]# read -p "請輸入字符串:" a b
請輸入字符串:12 34
[root@localhost ~]# echo $a $b
12 34