2016-02-26 29 views
0

我在使用toupper()在gawk sub()中遇到問題。我正在使用&替代匹配字符串的功能。gawk sub()與&符和toupper()不起作用

$ gawk '{sub(/abc/, toupper("&")); print $0; }' 
xabcx 
xabcx 

我預計:

xABCx 

變種toupper()但沒有&&但沒有toupper()工作:

$ gawk '{sub(/abc/, toupper("def")); print $0; }' 
xabcx 
xDEFx 

$ gawk '{sub(/abc/, "-&-"); print $0; }' 
xabcx 
x-abc-x 

它與tolower()同樣失敗。我誤解了&的工作原理嗎? (使用gawk 3.1.x和最新的4.1.3進行測試)。

回答

2

我想我看看發生了什麼:toupper函數正在評估第一個,在子構造替換字符串之前。

所以,你得到

sub(/abc/, toupper("def")) => sub(/abc/, "DEF") 

和不那麼有用

sub(/abc/, toupper("&")) => sub(/abc/, "&") 

要得到你想要的結果,你必須先提取了比賽,大寫它,然後執行取代:

$ echo foobar | gawk '{sub(/o+/, toupper("&")); print}' 
foobar 
$ echo foobar | gawk '{ 
    if (match($0, /o+/, m)) { 
     replacement = toupper(m[0]) 
     sub(/o+/, replacement) 
    } 
    print 
}' 
fOObar 

或者,您不需要子,你可以這樣重建記錄:

echo foobar | gawk '{ 
    if (match($0, /o+/, m)) { 
     $0 = substr($0, 1, RSTART-1) toupper(m[0]) substr($0, RSTART+RLENGTH) 
    } 
    print 
}' 
+0

不錯的偵探工作!我明白爲什麼你這樣拼寫出來,但可能值得補充的是它可以簡化爲'gawk'匹配($ 0,/ o + /,m){sub(/ o + /,toupper(m [0])) )} 1''。 –

+1

@ed,我試過了,但是第一個'(。*)'太貪婪了,除了一個「o」以外,其他都沒有。 –

+0

我不確定哪個更好 - 'gawk'match($ 0,/ o + /, m){sub(/ o + /,toupper(m [0]))} 1''這使得你指定正則表達式兩次(對於複雜正則表達式來說是個問題),或者'gawk'匹配($ 0,/ o + /,m) {sub(m [0],toupper(m [0]))} 1''如果match()中使用的正則表達式匹配自身包含RE元字符串的字符串,則會導致問題。所有事情都考慮到了,我認爲使用substr()的最終腳本是解決這兩個問題的最佳方法。 –

相關問題