- 如果需要從字符串或者文件中截取兩個以上的變量怎么辦?
很簡單:
#!/bin/bash
re="^([^-]+)-(.*)$"
str="ABCDE-123456"
[[ $str =~ $re ]]
var1="${BASH_REMATCH[1]}"
var2="${BASH_REMATCH[2]}"
echo $var1
echo $var2
運行這個腳本,將會回顯:
ABCDE
123456
BASH_REMATCH是bash的內(nèi)置關(guān)鍵字,它是一個數(shù)組,用于存儲正則表達式中圓括號() 所表達的變量,這跟平時我們使用其他編程語言的時候沒有太大的區(qū)別,很簡單是吧?
- 如果匹配的項目不止一個且位置隨機,也就是平時我們說的“正則分組”又該怎么辦呢?bash沒有像python或者go那樣有專門的findall或者FindAllStringSubmatch之類方法,但可以通過一個簡單算法來完成:
#!/bin/bash
s='1234,2222,abc,311'
regex='([0-9]+)'
while [[ $s =~ $regex ]]; do
echo "${BASH_REMATCH[1]}"
s=${s#*"${BASH_REMATCH[1]}"}
done
運行這個腳本,將會回顯:
1234
2222
311
這里有一個竅門,每次匹配完的部分將會從s中剔除,然后重新對s進行賦值,直到字符串中再沒有可以匹配的項目為止,變相實現(xiàn)了匹配分組功能。
參考資料:
https://unix.stackexchange.com/questions/251013/bash-regex-capture-group
- 從文件中讀取內(nèi)容并匹配,這個也很簡單,就不再贅述了:
現(xiàn)有文件ss.json,內(nèi)容如下:
{
"server":"127.0.0.1",
"server_port":8888,
"local_address":"0.0.0.0",
"local_port":9999,
"password":"123abc",
"timeout":600,
"method":"aes-128-gcm"
}
我們想將server截取出來,在腳本里我們這么寫:
IFS='\n'
cat ss.json | while read line ; do
if [[ "$line" =~ \"server\":\"(.+?)\" ]]; then
echo IP Address is: ${BASH_REMATCH[1]}
fi
done
題外話:如果$line這個變量不加雙引號,則系統(tǒng)會自動摘掉換行符,將整個文件變成一個長字符串。此處如果加上雙引號 "$line" ,輸出的時候則是原汁原味按照文件本來的樣子輸出。
運行腳本,系統(tǒng)將回顯:
IP Address is: 127.0.0.1