2015-07-22 43 views
2

給出了以下句子:「東西我的#1例子!」,在bash中,我想用'test'替換'my'(我的包含)之前的所有東西。 我做:bash,問題與定期expectression

echo "something my #1 example!" | sed s/.+my/test/g 

預期的結果應該是:

test #1 example! 

,但實際的結果是:

something my #1 example! 

我假設它不能找到匹配的表達式,即使它在這裏工作:http://regexr.com/3beg4

回答

3

對於GNU sed(mo如果要繼續使用基本正則表達式,則需要使用擴展正則表達式(使用-r--regexp-extended標誌之一),或者跳過+

詳情請參閱下面的成績單:

pax> echo "something my #1 example!" | sed 's/.+my/test/g' 
something my #1 example! 

pax> echo "something my #1 example!" | sed -r 's/.+my/test/g' 
test #1 example! 

pax> echo "something my #1 example!" | sed 's/.\+my/test/g' 
test #1 example! 

由於每sed信息頁面:

基本和擴展正則表達式的唯一區別是在少數人的行爲字符:'?','+',括號,大括號'{}''|'

雖然基本的正則表達式需要這些進行轉義,如果你希望它們表現爲特殊字符,使用擴展的正則表達式時,如果你想讓他們匹配文字字符必須轉義。


如果你不使用sed有支持這個水平,你通常可以隨時打開'.+''..*',以達到同樣的效果。

+0

或者使用'\ +'作爲BRE。 –

+0

POSIX sed(GNU'sed --posix')不支持'-r'或'\ +'。使用'。*。my'可以工作,或者在你有bash的情況下查看我的答案,但是sed可能不是GNU。 –

+0

@Peter補充說明了這一點。 – paxdiablo

0

你說的bash正則表達式在你的問題標題中,然後寫了一些關於sed的東西。以下是如何做到這一點在純慶典:

foo="something my #1 example!"; 
while [[ $foo =~ (.+my)(.*) ]]; do # loop instead of if, for /g. 
    foo="test${BASH_REMATCH[2]}"; 
    # If your pattern can match the replacement, then just loop over BASH_REMATCH[2] 
done; 
echo "$foo" 

擊不具有取代正則表達式運算符,所以你必須通過捕捉(.*)前/後的部分要修改來模擬它。

如果要修改shell變量中的字符串,這可能比sed更有效。如果你只是過濾標準輸出到標準輸出,sed可以節省你編寫一個read循環,而bash在處理大型文本流時比sed/grep慢得多。