SHELL腳本攻略(學習筆記)--1.7 expr命令全解

来源:http://www.cnblogs.com/f-ck-need-u/archive/2017/07/24/7231832.html
-Advertisement-
Play Games

expr命令可以實現數值運算、數值或字元串比較、字元串匹配、字元串提取、字元串長度計算等功能。它還具有幾個特殊功能,判斷變數或參數是否為整數、是否為空、是否為0等。 先看expr命令的info文檔info coreutils 'expr invocation'的翻譯。 下麵將使用示例來介紹expr的 ...


expr命令可以實現數值運算、數值或字元串比較、字元串匹配、字元串提取、字元串長度計算等功能。它還具有幾個特殊功能,判斷變數或參數是否為整數、是否為空、是否為0等。

先看expr命令的info文檔info coreutils 'expr invocation'的翻譯。

16.4.1 字元串表達式
-------------------------
'expr'支持模式匹配和字元串操作。字元串表達式的優先順序高於數值表達式和
邏輯關係表達式。
 
'STRING : REGEX'
     執行模式匹配。兩端參數會轉換為字元格式,且第二個參數被視為
     正則表達式(GUN基本正則),它預設會隱含首碼"^"。隨後將第一個參數
     和正則模式做匹配。
 
     如果匹配成功,且REGEX使用了'\(''\)',則才表達式返回匹配到的
 
     如果匹配失敗,如果REGEX中使用了'\(''\)',則此表達式返回空字元
     串,否則返回為0。
 
     只有第一個'\(...\)'會引用返回的值;其餘的'\(...\)'只在正則表達式
     分組時有意義。
 
     在正則表達式中,'\+''\?''\|'分表代表匹配一個或多個,0個或1個
     以及兩端任選其一的意思。
 
'match STRING REGEX'
     等價於'STRING : REGEX''substr STRING POSITION LENGTH'
     返回STRING字元串中從POSITION開始,長度最大為LENGTH的子串。如果
     POSITION或LENGTH為負數,0或非數值,則返回空字元串。
 
'index STRING CHARSET'
     CHARSET中任意單個字元在STRING中最前面的字元位置。如果在STRING中完全
     不存在CHARSET中的字元,則返回0。見後文示例。
    
'length STRING'
     返回STRING的字元長度。
 
'+ TOKEN'
     將TOKEN解析為普通字元串,即使TOKEN是像MATCH或操作符"/"一樣的關鍵字。
     這使得'expr length + "$x"''expr + "$x" : '.*/\(.\)''可以正常被測試,
     即使"$x"的值可能是'/''index'關鍵字。這個操作符是一個GUN擴展。
     通用可移植版的應該使用'" $token" : ' \(.*\)''來代替'+ "$token"'。
 
   要讓expr將關鍵字解析為普通的字元,必須使用引號包圍。
 
16.4.2 算術表達式
--------------------------
 
'expr'支持普通的算術操作,算術表達式優先順序低於字元串表達式,高於邏輯關係
表達式。
 
'+ -'
     加減運算。兩端參數會轉換為整數,如果轉換失敗則報錯。
 
'* / %'
     乘,除,取模運算。兩端參數會轉換為整數,如果轉換失敗則報錯。
 
16.4.3 邏輯關係表達式
---------------------------
 
'expr'支持普通的邏輯連接和邏輯關係。它的優先順序最低。
 
'|'
     如果第一個參數非空且非0,則返回第一個參數的值,否則返回第二個參數
     的值,但要求第二個參數的值也是非空或非0,否則返回0。如果第一個參數
     是非空或非0時,不會計算第二個參數。
    
     經過測試,以上手冊內容是錯誤的。正確的應該是:如果第一個參數非0,則
     返回第一個參數的值,否則返回第二個參數。但如果任意一個參數為空,則報錯。
     除非空字元串使用引號包圍,此時將和0的處理方式一樣。
 
'&'
     如果兩個參數都非空且非0,則返回第一個參數,否則返回0。如果第一個參
     為0或為空,則不會計算第二個參數。
    
     經過測試,以上手冊內容是錯誤的。正確的應該是:如果兩個參數都非0,則
     返回第一個參數,否則返回0。但任意一個參數為空,則報錯。除非空字元串
     使用引號包圍,此時將和0的處理方式一樣。
 
'< <= = == != >= >'
     比較兩端的參數,如果為true,則返回1,否則返回0。
     "==""="的同義詞。"expr"首先嘗試將兩端參數轉換為整數,並做算術
     比較,如果轉換失敗,則按字元集排序規則做字元比較。
 
括弧'()'可以改變優先順序,但使用時需要使用反斜線對括弧進行轉義。
 
16.4.4 'expr'使用示例
-------------------------------
 
以下為expr的一些示例,其中有將shell的元字元使用引號包圍的示例。
 
   將shell中變數'foo'的值增加1:
 
     foo=$(expr $foo + 1)
 
   輸出變數路徑變數'$fname'中不包含'/'的文件名部分:
 
     expr $fname : '.*/\(.*\)' '|' $fname
    
     解釋:其中的'|'是expr中的連接符,只不過是被引號包圍防止被shell解析。
     例如$fname=/etc/hosts,則此表達式返回hosts,如果$fname=/usr/share/,則
     此表達式'|'的左邊為空,所以返回'|'右邊的值,即$fname,即返回/usr/share/。
 
   An example showing that '\+' is an operator:
 
     expr aaa : 'a\+'    # 解釋:因為REGEX部分沒有使用\(\),所以返回匹配的字元數
     => 3
 
     expr abc : 'a\(.\)c'  # 解釋:因為REGEX部分使用了\(\),所以返回匹配的字元
     => b
     expr index abcdef cz
     => 3
     expr index index a    # 解釋:因為第二個index是關鍵字
     error-> expr: syntax error
     expr index + index a  # 解釋:使用+將index關鍵字解析為普通字元串
     => 0

下麵將使用示例來介紹expr的用法,在介紹之前,需要註意三點:

(1).數值表達式("+ - * / %")和比較表達式("< <= = == != >= >")會先將兩端的參數轉換為數值,轉換失敗將報錯。所以可藉此來判斷參數或變數是否為整數。

(2).expr中的很多符號需要轉義或使用引號包圍。

(3).所有操作符的兩邊,都需要有空格。

以下是expr示例。

(1)."string : REGEX"字元串匹配示例。要輸出匹配到的字元串結果,需要使用"\("和"\)",否則返回的將是匹配到的字元串數量。

[root@xuexi ~]# expr abcde : 'ab\(.*\)'
cde

[root@xuexi ~]# expr abcde : 'ab\(.\)'
c

[root@xuexi ~]# expr abcde : 'ab.*'  
5

[root@xuexi ~]# expr abcde : 'ab.'   
3

[root@xuexi ~]# expr abcde : '.*cd*'
4

註意,由於REGEX中隱含了"^",所以使得匹配時都是從string首字元開始的。

[root@xuexi ~]# expr abcde : 'cd.*'  
0

之所以為0,是因為真正的正則表達式是"^cd.*",而abcde不是c開頭而是a開頭的,所以無法匹配到任何結果。因此,任何字元串匹配時,都應該從首字元開始。

字元串匹配時,會先將兩端參數轉換為字元格式。

(2)."index string chars"用法示例。

該表達式是從string中搜索chars中某個字元的位置,這個字元是string中最靠前的字元。例如:

[root@xuexi ~]# expr index abcde dec
3

該命令將對字元串"dec"逐字元分解,首先分解得到第一個字元d,從abcde中搜索到d的位置為4,再分解得到第二個字元e,該字元在abcde中的位置為5,最後得到的字元是c,該字元在abcde中的位置為3。其中3是最靠前的字元,所以命令返回的結果為3。

[root@xuexi ~]# expr index abcde xdc
3

如果chars中的所有字元都不存在於string中,則返回0。

[root@xuexi ~]# expr index abcde 1
0

[root@xuexi ~]# expr index abcde 1x
0

(3)."substr string pos len"用法示例。

該表達式是從string中取出從pos位置開始長度為len的子字元串。如果pos或len為非正整數時,將返回空字元串。

[root@xuexi ~]# expr substr abcde 2 3
bcd

[root@xuexi ~]# expr substr abcde 2 4
bcde

[root@xuexi ~]# expr substr abcde 2 5
bcde

[root@xuexi ~]# expr substr abcde 2 0

[root@xuexi ~]# expr substr abcde 2 -1

(4)."length string"用法示例。該表達式是返回string的長度,其中string不允許為空,否則將報錯,所以可以用來判斷變數是否為空。

[root@xuexi ~]# expr length abcde
5

[root@xuexi ~]# expr length 111
3

[root@xuexi ~]# expr length $xxx
expr: syntax error

[root@xuexi ~]# if [ $? -ne 0 ];then echo '$xxx is null';fi
$xxx is null

(5)."+ token"用法示例。

expr中有些符號和關鍵字有特殊意義,如"match"、"index"、"length",如果要讓其成為字元,使用該表達式將任意token強制解析為普通字元串。

[root@xuexi ~]# expr index index d
expr: syntax error

[root@xuexi ~]# expr index length g
expr: syntax error

[root@xuexi ~]# expr index + length g
4

其實可以通過字元串匹配的方式,將關鍵字轉換為字元串。例如:

[root@xuexi ~]# expr index 'length : "\(length\)"' g 
4

對值為關鍵字的變數來說,則無所謂。

[root@xuexi ~]# len=lenght

[root@xuexi ~]# expr index $len g
4

(6).算術運算用法示例。

[root@xuexi ~]# expr 1 + 2
3

[root@xuexi ~]# a=3
[root@xuexi ~]# b=4

[root@xuexi ~]# expr $a + $b
7

[root@xuexi ~]# expr 4 + $a
7

[root@xuexi ~]# expr $a - $b
-1

算術乘法符號"*"因為是正則表達式中的元字元,所以要轉義,可以使用引號包圍,或者使用反斜線。

[root@xuexi ~]# expr $a * $b
expr: syntax error

[root@xuexi ~]# expr $a '*' $b
12

[root@xuexi ~]# expr $a \* $b
12

[root@xuexi ~]# expr $b / $a    # 除法只能取整數
1

[root@xuexi ~]# expr $b % $a
1

任意操作符兩端都需要有空格,否則:

[root@xuexi ~]# expr 4+$a 
4+3

[root@xuexi ~]# expr 4 +$a
expr: syntax error

由於expr在進行算術運算時,首先會將操作符兩邊的參數轉換為整數,任意一端轉換失敗都將會報錯,所以可以用來判斷參數或變數是否為整數。

[root@xuexi ~]# expr $a + $c
expr: non-integer argument

[root@xuexi ~]# if [ $? != 0 ];then echo '$a or $c is non-integer';fi          
$a or $c is non-integer

(7).比較操作符< <= = == != >= >用法示例。其中"<"和">"是正則表達式正的錨定元字元,且"<"會被shell解析為重定向符號,所以需要轉義或用引號包圍。

這些操作符會首先會將兩端的參數轉換為數值,如果轉換成功,則採用數值比較,如果轉換失敗,則按照字元集的排序規則進行字元大小比較。比較的結果若為true,則expr返回1,否則返回0。

[root@xuexi ~]# a=3

[root@xuexi ~]# expr $a = 1
0

[root@xuexi ~]# expr $a = 3
1

[root@xuexi ~]# expr $a \* 3 = 9
1

[root@xuexi ~]# expr abc \> ab
1

[root@xuexi ~]# expr akc \> ackd
1

(8).邏輯連接符號"&"和"|"用法示例。這兩個符號都需要轉義,或使用引號包圍。

以下是官方文檔中給出的解釋,但實際使用過程中是不完全正確的。

"&"表示如果兩個參數同時滿足非空且非0,則返回第一個參數的值,否則返回0。且如果發現第一個參數為空或0,則直接跳過第二個參數不做任何計算。

"|"表示如果第一個參數非空且非0,則返回第一個參數值,否則返回第二個參數值,但如果第二個參數為空或為0,則返回0。且如果發現第一個參數非空或非0,也將直接跳過第二個參數不做任何計算。

正確的應該是:

"&"表示如果兩個參數都非0,則返回第一個參數,否則返回0。但任意一個參數為空,則expr報錯。除非空字元串使用引號包圍,則處理方法和0一樣。

"|"表示如果第一個參數非0,則返回第一個參數的值,否則返回第二個參數。但如果任意一個參數為空,則expr報錯。除非空字元串使用引號包圍,則處理方法和0一樣。

[root@xuexi ~]# expr $abc '|' 1
expr: syntax error

[root@xuexi ~]# expr "$abc" '|' 1
1

[root@xuexi ~]# expr "$abc" '&' 1 
0

[root@xuexi ~]# expr $abc '&' 1 
expr: syntax error

[root@xuexi ~]# expr 0 '&' abc
0

[root@xuexi ~]# expr abc '&' 0
0

[root@xuexi ~]# expr abc '|' 0
abc

[root@xuexi ~]# expr 0 '|' abc  
abc

[root@xuexi ~]# expr abc '&' cde
abc

[root@xuexi ~]# expr abc '|' cde
abc

 

回到系列文章大綱:http://www.cnblogs.com/f-ck-need-u/p/7048359.html

轉載請註明出處:http://www.cnblogs.com/f-ck-need-u/p/7231832.html


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 以管理員的啟動cmd 進入安裝目錄下 輸入: mongod --auth --port 3406 --dbpath=庫地址 --logpath= 全地址 --install --serviceName "自定義名稱" 註:庫地址可只指定到文件夾,LOG地址需指定到具體文件 --auth 啟用權根控制 ...
  • 很多時候,大家都知道,浮點型這個東西,本身存儲就是一個不確定的數值,你永遠無法知道,它是 0 = 0.00000000000000123 還是 0 = 0.00000000000999這樣的東西。也許一開始使用的時候沒有問題,但是有時候做統計的時候,就會看出端倪 簡單的舉個例子,就知道統計的時候,有 ...
  • 一、MySQL數據類型 1.數值型 SMALLINT: 2個位元組 INT: 4個位元組 // age int(10) INTEGER:INT的同義詞 BIGINT : 8個位元組 FLOAT : 4個位元組 DOUBLE : 8個位元組 //score float(10,2) 2.字元串(字元)類型 CHA ...
  • 一、資料庫的基本概念 資料庫: 以一定方式儲存在一起、能為多個用戶共用、具有儘可能小的冗餘度的特點、是與應用程式彼此獨立的數據集合。 DBMS(DataBase Management System,資料庫管理系統)和資料庫。平時談到“資料庫”可能有兩種含義:MSSQLServer、Oracle等某種 ...
  • Jexus 即 Jexus Web Server,簡稱JWS,是Linux平臺上的一款ASP.NET WEB伺服器,是 Linux、Unix、FreeBSD 等非Windows系統架設 ASP.NET WEB 伺服器的核心程式,是企業級ASP.NET跨平臺部署的一種可選方案。與其它WEB伺服器相比, ...
  • gawk 程式是Unix中原始awk程式的GNU版本。gawk程式讓流編輯器邁上了一個新的臺階,它提供了一種編程語言而不只是編輯器命令。在gawk編程語言中,可以完成下麵的事情: (1)定義變數來保存數據; (2)使用算數和字元串操作符來處理數據; (3)使用結構化編程概念(比如if then語句和 ...
  • 本文目錄: 1.6.1 基本整數運算 1.6.2 bc命令高級算術運算 使用let、$(())或$[]進行基本的整數運算,使用bc進行高級的運算,包括小數運算。其中expr命令也能進行整數運算,還能判斷參數是否為整數,具體用法見expr命令全解。 1.6.1 基本整數運算 [root@xuexi t ...
  • 在一開始使用Ubuntu時還是滿興奮的,但是在多次登錄系統後發現Ubuntu有自己設置的帳號和密碼之外,還有一個“客人登錄”。細心的人就會發現客人登錄是不需要帳號和密碼的,直接點擊就能登錄。雖然說客人登錄退出後會刪除所有設置和操作,但我還是不放心。我在網上找了一些方法,終於被我找到一個比較合適的了。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...