2017-01-28 4 views
0

Я хочу заменить каждый экземпляр word, который не имеет префикса pre, с preword с использованием sed. Поэтому word в preword не следует заменять, но одиночный 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 's/\bword\b/preword/g' file 

\b является границей нулевой ширины слово

+0

Хорошо, что сделал трюк! Спасибо @Cyrus! :) – samurdhilbk

+2

Недостаток: он не заменит «микрософт». – Cyrus

+0

Я вижу. Но мое приложение действительно хочет заменить только слова, которые имеют границу в начале. – samurdhilbk

3

Вам не нужно, чтобы избежать "слова" с "пре" перед тем, соответствовать " pre "и систематически их заменять:

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' и backticks вызовет ошибку, не так ли? –

+0

@BenjaminW. Исправлена. Благодарю. – slitvinov

 Смежные вопросы

  • Нет связанных вопросов^_^