2015-09-29 33 views
0

使用sed,如何在關鍵字結束後的x個字符內替換關鍵字後面的字符,但只有。例如,假設字符串:替換關鍵字後面和距離內的字符

foo bar baz quz

讓我們假設關鍵字是bar和性格ž是與性格被替換,但對最終的僅在3個字符關鍵字(不包括空格)。

期望的結果將是:

foo bar bat quz

編輯:我想是的可以在此指明,但我不確定如何擴展正則表達式的使用。

sed -re 's/(::bar) some_regex_magic_here /' infile

+0

像這樣的事情? https://regex101.com/r/gY8tS6/1 – lintmouse

+0

@dustmouse您的建議遭受與響應用戶* Joe *所述相同的問題:'echo「foo bar bzz quz」| sed -re's /(bar。{3})z/\ 1t /''給出'foo bar bzt quz',而不是所需的'foo bar btt quz'。 –

回答

1

使用awk的,你可以這樣做:

s="foo bar baz quz" 

awk -v kw='bar' -v pos=3 'p=index($0, kw){n=p+length(kw)+1; s=substr($0, n, pos); 
    gsub(/z/, "t", s); $0=substr($0, 1, n-1) s substr($0, n+pos)} 1' <<< "$s" 

輸出:

foo bar bat quz 

更多的測試:

s='foo bar bzz quz' 
awk -v kw='bar' -v pos=3 'p=index($0, kw){n=p+length(kw)+1; s=substr($0, n, pos); 
    gsub(/z/, "t", s); $0=substr($0, 1, n-1) s substr($0, n+pos)} 1' <<< "$s" 
foo bar btt quz 
+0

謝謝。但是,當應用於多行時,您的* awk *代碼省略了不含關鍵字的行。例如:'echo -e「foo bar bzz quz \ nfoo bzz quz \ nfoo bar bzz quz」> tmp && awk -v kw ='bar'-v pos = 3'p = index($ 0,kw){n = p +長度(千瓦)1; s = substr($ 0,n,pos); gsub(/ z /,「t」,s); print substr($ 0,1,n-1)s substr($ 0,n + pos)}'tmp'你能修改你的代碼嗎? –

+0

好的檢查我更新的awk命令。 – anubhava

+1

用戶* anubhava *的答案很好!感謝他的努力。 –

0

你可以用下面的命令做到這一點:

sed -E 's/(bar[[:space:]]*(.[[:space:]]*){0,2})z/\1t/'` 

例子:

echo "foo bar baz quz" | sed -E 's/(bar[[:space:]]*(.[[:space:]]*){0,2})z/\1t/' 

它通過捕獲bar其次是空白的任何金額,但僅達2非空格字符,然後z並將其替換爲捕獲組1,然後是t-E是OSX的擴展正則表達式標誌,如有必要,請將其更改爲擴展正則表達式標誌。

+1

謝謝。雖然你的代碼在上面的例子中起作用,但當有問題的角色出現多次時,它就會失敗。例如:'echo「foo bar bzz quz」| sed -re's /(bar(\ s * [^ \ s]){0,3})z/\ 1t /'' –

+1

sed不再是您的工具,那麼請參閱awk答案。 – Joe

相關問題