使用sed,如何在關鍵字結束後的x個字符內替換關鍵字後面的字符,但只有。例如,假設字符串:替換關鍵字後面和距離內的字符
foo bar baz quz
讓我們假設關鍵字是bar
和性格ž是與性格噸被替換,但對最終的僅在3個字符關鍵字(不包括空格)。
期望的結果將是:
foo bar bat quz
編輯:我想是的可以在此指明,但我不確定如何擴展正則表達式的使用。
sed -re 's/(::bar) some_regex_magic_here /' infile
使用sed,如何在關鍵字結束後的x個字符內替換關鍵字後面的字符,但只有。例如,假設字符串:替換關鍵字後面和距離內的字符
foo bar baz quz
讓我們假設關鍵字是bar
和性格ž是與性格噸被替換,但對最終的僅在3個字符關鍵字(不包括空格)。
期望的結果將是:
foo bar bat quz
編輯:我想是的可以在此指明,但我不確定如何擴展正則表達式的使用。
sed -re 's/(::bar) some_regex_magic_here /' infile
使用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
謝謝。但是,當應用於多行時,您的* 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'你能修改你的代碼嗎? –
好的檢查我更新的awk命令。 – anubhava
用戶* anubhava *的答案很好!感謝他的努力。 –
你可以用下面的命令做到這一點:
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的擴展正則表達式標誌,如有必要,請將其更改爲擴展正則表達式標誌。
謝謝。雖然你的代碼在上面的例子中起作用,但當有問題的角色出現多次時,它就會失敗。例如:'echo「foo bar bzz quz」| sed -re's /(bar(\ s * [^ \ s]){0,3})z/\ 1t /'' –
sed不再是您的工具,那麼請參閱awk答案。 – Joe
像這樣的事情? https://regex101.com/r/gY8tS6/1 – lintmouse
@dustmouse您的建議遭受與響應用戶* Joe *所述相同的問題:'echo「foo bar bzz quz」| sed -re's /(bar。{3})z/\ 1t /''給出'foo bar bzt quz',而不是所需的'foo bar btt quz'。 –