2017-01-28 105 views
0

我想用sed替換word的每個不具有前綴pre的實例以及preword。因此wordpreword不應該被替換,但一個word應該替換爲preword使用sed替換不以某個前綴開頭的單詞

我想平常負向後看正則表達式,像這樣

sed -E -i 's/(?<!pre)word/preword/g'

,但它給我的錯誤

sed: -e expression #1, char 22: Invalid preceding regular expression

我讀過GNU sed有一些不同的方法治療正則表達式。我能做些什麼來完成這件事?

+0

應該'foreword'成爲'forepreword'?明確您的要求並展示簡潔,可測試的樣本輸入和預期的輸出,涵蓋您的所有用例。 –

回答

2

隨着GNU sed的:

sed 's/\bword\b/preword/g' file 

\b是零寬度字邊界

+0

好吧,這個伎倆!謝謝@Cyrus! :) – samurdhilbk

+2

缺點:它不會取代'microsoftword'。 – Cyrus

+0

我明白了。但是我的應用程序實際上只想替換開始時具有邊界的單詞。 – samurdhilbk

3

你不必爲了避免 「字」 與 「前」 之前,匹配「預先「,並系統地更換:

sed -E 's/(pre)?word/preword/g' 

其他方式(更一般),你把捕獲組的所有不是「前」:

sed -E 's/(^|[^e]|^e|[^r]e|^re|[^p]re)word/\1preword/g' 
0

如果你需要一個複雜的正則表達式,你也可以考慮 寫一個微小的解析器。

$ cat r.awk 
BEGIN { 
    re_wrd = "^[A-Za-z]+" # what we consider a word 
    re_sep = "^."  # the rest is a separator 
} 

function advance() { # sets `tag' and `tok'; eats a part of `line' 
    if  (match(line, re_wrd)) tag = "wrd" 
    else if (match(line, re_sep)) tag = "sep" 
    tok = substr(line, 1,   RLENGTH) 
    line = substr(line, RLENGTH + 1  ) 
} 

function process_sep() { # copy to output 
    ans = ans tok 
} 

function process_wrd() { 
    sub(/^word/, "preword", tok) # replace only at the beginning 
    ans = ans tok 
} 

{ 
    line = $0; ans = tag = tok = "" 
    while (length(line) > 0) { 
     advance() 
     # uncomment for tracing 
     # print tag, "<" tok ">" | "cat 1>&2" 
     if  (tag == "sep") process_sep() 
     else if (tag == "wrd") process_wrd() 
    } 
    print ans 
} 

用法:

$ echo 'preword...microsoftword word wordword,word.word-preword' | awk -f r.awk 
preword...microsoftword preword prewordword,preword.preword-preword 

跟蹤:

wrd <preword> 
sep <.> 
sep <.> 
sep <.> 
wrd <microsoftword> 
sep < > 
wrd <word> 
sep < > 
wrd <wordword> 
sep <,> 
wrd <word> 
sep <.> 
wrd <word> 
sep <-> 
wrd <preword> 
+1

帶'echo'和反引號的用法示例會導致錯誤,不是嗎? –

+0

@BenjaminW。固定。謝謝。 – slitvinov

相關問題