Shell裡內建陣列BASH_REMATCH[n]個人解析
先引用一段資料,出自:http://bbs.chinaunix.net/thread-4125147-1-1.html
紅色註釋為個人新增
--------------------------------------------------------------搬運內容分割線----------------------------------------------------------------
從 bash 3以上版本里,已經自帶正則匹配的功能, 很多情況下,可以不用awk/sed來做。 比如這個需求:
-
<List>
-
<Job id="1" name="abc"/>
-
<Job id="2" name="zyz"/>
-
<Job id="3" name="beew"/>
- </List>
-
abc | 1
-
zyz | 2
- beew | 3
-
#!/bin/bash
-
while read line; do //讀入變數line
-
if [[ $line =~ id=\"([0-9]+).*name=\"([^\"]*) ]]; then
//子模式1為([0-9]+);子模式2為([^\"]*)
-
echo "${BASH_REMATCH[2]} | ${BASH_REMATCH[1]}"
-
fi
- done < file
把樓下@rogantianwz的回覆帖在這裡,解釋的很不錯。
- 雙目運算子=~;它和==以及!=具有同樣的優先順序。如果使用了它,則其右邊的字串就被認為是一個擴充套件的正則表示式來匹配。如果字串和模式匹配,則返回值是0,否則返回1。如果這個正則表示式有語法錯誤,則整個條件表示式的返回值是2。如果打開了shell的nocasematch 選項則匹配時不考慮字母的大小寫。模式的任何部分都可以被引用以強制把其當作字串來匹配。由正則表示式中括號裡面的子模式匹配的字串被儲存在陣列變數BASH_REMATCH 中。BASH_REMATCH 中下標為0的元素是字串中與整個正則表示式匹配的部分。BASH_REMATCH 中下標為n的元素是字串中與第n 個括號裡面的子模式匹配的部分。
--------------------------------------------------------------搬運內容分割線----------------------------------------------------------------
我的理解:子模式1為匹配出現一次或多次(+號的作用)任意0~9字元;子模式2為出現零次或多次(*號的作用)的非雙引號"字元,其中[^\"]取一切非雙引號單個字元,反斜槓\用來轉義雙引號"。接下來的echo "${BASH_REMATCH[n]}"中,按照先讀取匹配子模式2的陣列內容BASH_REMATCH{2},即上例中的abc,xyz,beew等等,接著列印豎線|,最後讀取匹配子模式1的陣列內容,即1,2,3。下面搬運一個匹配ip地址的指令碼
出處:http://www.yunweipai.com/archives/4660.html
--------------------------------------------------------------搬運內容分割線----------------------------------------------------------------
在運維場景下,我們經常需要在伺服器上用正則表示式來匹配IP地址。
shell和其它程式語言一樣,也可以使用正則分組捕獲,不過不能使用 $1或\1這樣的形式來捕獲分組,可以通過陣列${BASH_REMATCH}來獲得,如${BASH_REMATCH[1]},${BASH_REMATCH[N]}
下面以ip="121.0.2.2"為例,shell指令碼程式碼如下(當然,你要做成更通用互動式的指令碼,可以通過expect來實現):
#!/bin/baship="121.0.2.2"
if [[ $ip =~ ^([0-9]{1,2}|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]{1,2}|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]{1,2}|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]{1,2}|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$ ]]
then
echo "Match"
echo ${BASH_REMATCH[1]}
echo ${BASH_REMATCH[2]}
echo ${BASH_REMATCH[3]}
echo ${BASH_REMATCH[4]}
else
echo "Not match"
fi
--------------------------------------------------------------搬運內容分割線----------------------------------------------------------------
我的分析:
如果符合ip地址定義範圍,則返回結果為
Match
121
0
2
2
否則返回Not match(執行結果已實機驗證)
if判斷語句裡的正則表示式[0-9]{1,2}|1[0-9][0-9]|2[0-4][0-9]|25[0-5]意為匹配符合ip地址定義原則的欄位:當總位數為1~2時,符合要求的取值為0~99,當總位數為3的時候,符合的取值區間為100~199,200~249,250~255,其中豎線 | 的作用是或邏輯運算