2011-04-11 51 views
8

如何在BASH中的替換表達式中包含正則表達式匹配?如何在bash中引用捕獲正則表達式替換

非工作示例:

#!/bin/bash 
name=joshua 
echo ${name//[oa]/X\1} 

我希望輸出jXoshuXa\1由匹配的字符被替換。

雖然這並不實際工作,但輸出jX1shuX1

+2

我在我的bash(4.1.5)版本中看不到任何關於能夠使用'$ {foo/bar/baz}'語法來執行正則表達式替換的內容。你有什麼參考資料爲什麼你認爲你應該能夠做到這一點? – 2011-04-11 17:20:05

+0

我不知道我在哪裏偶然發現它,但它確實有效。使用上面的示例,您可以看到它正在用'X'替換'o'和'a'。很漂亮。 – joshuapoehls 2011-04-11 17:29:58

+0

參見http://tldp.org/LDP/abs/html/parameter-substitution.html,對此的描述大概是頁面下方的3/4。 – 2011-04-11 17:31:59

回答

7
bash> name=joshua 
bash> echo $name | sed 's/\([oa]\)/X\1/g' 
jXoshuXa 
+0

如果你打算達到sed,這很簡單:'s/[oa]/X&/ g' – 2011-04-11 17:25:52

+0

謝謝!我希望能夠在不調用'sed'的情況下做到這一點,但這也應該是一樣的。 – joshuapoehls 2011-04-11 17:32:11

22

也許並不那麼直觀,可以說是模糊的,因爲所有的地獄,但在完整的精神,在我們等待BASH捕捉替代到達,以下是目前可能的。

#!/bin/bash 
name='joshua' 
[[ $name =~ ([ao].*)([oa]) ]] && \ 
    echo ${name/$BASH_REMATCH/X${BASH_REMATCH[1]}X${BASH_REMATCH[2]}} 

在那個例子中,我們知道我們在找什麼。接近匹配全部或全局正則表達式對應的下面的例子將貪婪地匹配到沒有前綴X的集合的最後一次出現,並且繼續向後直到沒有剩餘。

#/bin/bash 
name='joshua' 
while [[ $name =~ .*[^X]([oa]) ]]; do 
    name=${name/$BASH_REMATCH/${BASH_REMATCH:0:-1}X${BASH_REMATCH[1]}} 
done 
echo $name 

這個例子的工作方式與落後表達/(?<!X)([oa])/X\1/的目光假設只關心O和不具有前綴一個X一個字符。

輸出兩個例子

jXoshuXa 

的nJoy!