shell中’-gt’與’>’的區別


  參考: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 ~]# 

   使用上例中的方法,在比較日期的前后時,我們就不用必須轉換字符串格式的日期了,省去了一個步驟,還是比較方便的。








免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM