參考:http://www.zsythink.net/archives/2224
bash中,如果想要比較兩個數字的大小,最常用的關系運算符就是 "-gt"或者"-lt"了
最簡單的示例如下
[root@node1 ~]# a=3 [root@node1 ~]# b=2 [root@node1 ~]# [ $a -gt $b ] [root@node1 ~]# echo $? 0 [root@node1 ~]# [[ $a -gt $b ]] [root@node1 ~]# echo $? 0 [root@node1 ~]# [ $a -lt $b ] [root@node1 ~]# echo $? 1 [root@node1 ~]# [[ $a -lt $b ]] [root@node1 ~]# echo $? 1 [root@node1 ~]#
正如上圖所示,a=3,b=2,當比較兩個變量時,判斷變量a的值是否大於變量b的值時,返回值為0,即結果為真,判斷變量a的值是否小於變量b的值時,返回值為1,即結果為假(非零值為假)。
但是細心如你一定注意到了,在上例中,兩個變量的值均為數字,所以我們可以使用關系運算符"-gt"或者"-lt"比較兩個數字的大小。
如果是兩個字符串進行比較呢?
我們知道,字符在ASCII表中都有對應的值
字母a在ASCII表中對應的十進制數值為97
字母b在ASCII表中對應的十進制數值為98
也就是說,字母a的ASCII值應該是小於字母b的ASCII值的
那么,我們使用關系運算符,比較一下字母a與字母b,看看能否與我們想象的一樣,示例如下
[root@node1 ~]# [ "a" -gt "b" ] -bash: [: a: 期待整數表達式 [root@node1 ~]# [ "a" -lt "b" ] -bash: [: a: 期待整數表達式
可以看到,當我們直接使用 "-gt"或者"-lt"比較兩個字符串時,語法錯誤,直接報錯了,看來不能這樣用。
聰明如你,一定想到了,我們把上例中的"單中括號"換成"雙中括號"試試,示例如下
[root@node1 ~]# [[ "a" -gt "b" ]] [root@node1 ~]# [[ "a" -lt "b" ]] [root@node1 ~]# [[ "a" -gt "b" ]] [root@node1 ~]# echo $? 0 [root@node1 ~]# [[ "a" -lt "b" ]] [root@node1 ~]# echo $? 1
如上圖所示,雖然語法上沒有報錯,但是結果並不正確
字母a的ASCII值明明是小於字母b的ASCII值的
但是,判斷字符"a"的ASCII值是否大於字符"b"的ASCII值時,返回值為0(為真),也就是說,與我們期望的值並不一樣,換句話說就是,通過 "-gt"或者"-lt"並不能准確的比較出兩個字符的ASCII值的大小。
所以,在比較兩個字符的ASCII值的大小時,我們需要使用另一種符號,就是">"或者"<"
沒錯,就是我們最常用的"大於號"或者"小於號",示例如下
[root@node1 ~]# [[ "a" > "b" ]] [root@node1 ~]# echo $? 1 [root@node1 ~]# [[ "a" < "b" ]] [root@node1 ~]# echo $? 0 [root@node1 ~]#
如上圖所示,當我們想要比較兩個字符的ASCII值時,則需要使用">"或者"<"
但是需要注意的一點是,在使用單中括號時,如果想要使用">"或者"<",則需要轉義,示例如下
[root@node1 ~]# [ "a" > "b" ] [root@node1 ~]# echo $? 0 [root@node1 ~]# [ "a" < "b" ] [root@node1 ~]# echo $? 0 [root@node1 ~]# [ "a" \> "b" ] [root@node1 ~]# echo $? 1 [root@node1 ~]# [ "a" \< "b" ] [root@node1 ~]# echo $? 0 [root@node1 ~]#
正如上圖所示,當使用單中括號時,如果想要使用">"或者"<",則需要轉義,如果沒有對符號進行轉義,雖然語法上沒有報錯,但是並不能正確的判斷出字符的ASCII值的大小,如上圖所示,當使用單中括號時,只有對符號進行轉義后,才能夠正確的判斷出兩個字符的ASCII值的大小。
綜上所述,我們可以得出 結論:
在shell中,"-gt"或者"-lt"只能用於比較兩個數字的大小,當我們想要比較兩個字符的ASCII值時,則必須使用">"或者"<",而且需要注意,當使用"雙中括號"進行判斷時,">"或者"<"不用轉義即可正常使用,當使用"單中括號"進行判斷時,">"或者"<"需要轉義后才能正常使用。
那么我們來看一個應用中的小例子
如果我們想要比較兩個日期的前后,我們可以將日期的格式轉化為純數字的格式,然后進行比較,數字較大的對應的日期應該較晚,示例如下
[root@node1 ~]# [[ 20170730 > 20170329 ]] [root@node1 ~]# echo $? 0 [root@node1 ~]# [[ 20170730 < 20170329 ]] [root@node1 ~]# echo $? 1 [root@node1 ~]# [[ 20170730 -gt 20170329 ]] [root@node1 ~]# echo $? 0 [root@node1 ~]# [[ 20170730 -lt 20170329 ]] [root@node1 ~]# echo $? 1 [root@node1 ~]#
但是,有時候我們直接獲取到的日期格式可能是字符串格式的,比如"2017-07-30",難道我們必須要把這種格式轉換成純數字格式以后再對比嗎?不是的,我們可以直接對比相同字符串格式的日期,日期較晚的字符串轉換成ASCII以后,ASCII值應該更大,示例如下
[root@node1 ~]# [[ "2017-07-30" > "2017-03-29" ]] [root@node1 ~]# echo $? 0 [root@node1 ~]# [[ "2017-07-30" < "2017-03-29" ]] [root@node1 ~]# echo $? 1 [root@node1 ~]# [ "2017-07-30" \> "2017-03-29" ] [root@node1 ~]# echo $? 0 [root@node1 ~]# [ "2017-07-30" \< "2017-03-29" ] [root@node1 ~]# echo $? 1 [root@node1 ~]#
使用上例中的方法,在比較日期的前后時,我們就不用必須轉換字符串格式的日期了,省去了一個步驟,還是比較方便的。